asp.net 验证失败时,无法将“无效”类添加到自定义组件

9gm1akwq  于 2023-01-06  发布在  .NET
关注(0)|答案(1)|浏览(92)

我已经创建了一个继承自InputBase的自定义Select组件。除了验证之外,一切正常。我不确定如何确保将“invalid”类添加到下面的自定义表单组件中,就像添加到其他Blazor表单组件(如InputText)中一样:
Select.razor

<div id="select-@Id" class="component-select" @ref="ReferenceToDiv">
    @foreach (var option in Options)
    {
        <div @onclick="() => OnSelect(option)" class="option">@option.Text</div>
    }
</div>

Select.razor.cs

namespace Accounting.Web.Components.Forms
{
    public partial class SelectOption
    {
        public string Text { get; set; } = default!;
        public string Value { get; set; } = default!;
    }

    public partial class Select<TValue> : InputBase<TValue>
    {
        [Parameter]
        public ElementReference ReferenceToDiv { get; set; }

        [Parameter]
        public string Id { get; set; } = String.Empty;

        [Parameter]
        public List<SelectOption> Options { get; set; }

        [Parameter]
        public string PlaceholderText { get; set; } = "Select...";

        [Parameter]
        public EventCallback<Select<TValue>> OnSelected { get; set; } = default!;

        public SelectOption SelectedOption { get; set; } = default!;

        protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage)
        {
            if (BindConverter.TryConvertTo<TValue>(value, null, out result))
            {
                validationErrorMessage = null;
                return false;
            }
            else
            {
                validationErrorMessage = "Err : Select value";
                return false;
            }
        }

        public void OnSelect(SelectOption? option)
        {
            TValue tmpValue;
            
            option.Value = "";  // this line is to test the validation, it should always fail and add 'invalid' clas to the component classes

            BindConverter.TryConvertTo<TValue>(option.Value, null, out tmpValue);
            CurrentValue = tmpValue;            
            SelectedOption = option;
        }
    }
}

Index.razor

<EditForm Model="@AddDto" class="card card-body bg-light mt-5" OnValidSubmit="OnValidSubmit">
    <DataAnnotationsValidator />

    <Accounting.Web.Components.Forms.Select             
        Id="InvestmentEntitySelect"
        Options="@entityOptions" @bind-Value="AddDto.InvestmentEntityId">
    </Accounting.Web.Components.Forms.Select>

    <button type="submit" class="btn btn-primary full-width">Add</button>        
</EditForm>
6tqwzwtp

6tqwzwtp1#

请尝试将@CssClass添加到类中-〈div id=“select-@Id”class=“component-select @CssClass”@ref=“ReferenceToDiv”〉。
它在ComponentBase中的工作方式是:

protected string CssClass
    {
        get
        {
            var fieldClass = EditContext?.FieldCssClass(FieldIdentifier);
            return AttributeUtilities.CombineClassNames(AdditionalAttributes, fieldClass) ?? string.Empty;
        }
    }

其中EditContext?.FieldCssClass(FieldIdentifier)是一个扩展方法,它根据FieldIdentifier定义的字段是否有验证消息返回有效/无效的css。该方法将此css字符串与组件属性class中提供的css组合在一起。
这在如下实现中使用(这是InputSelect):

protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        builder.OpenElement(0, "select");
        builder.AddMultipleAttributes(1, AdditionalAttributes);
        builder.AddAttributeIfNotNullOrEmpty(2, "class", CssClass);
        builder.AddAttribute(3, "multiple", _isMultipleSelect);
        //...

为了记录,实际GetFieldCssClass代码为:

public virtual string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
    {
        var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
        if (editContext.IsModified(fieldIdentifier))
        {
            return isValid ? "modified valid" : "modified invalid";
        }
        else
        {
            return isValid ? "valid" : "invalid";
        }
    }

相关问题