微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Blazor - 嵌套组件不会突出显示无效字段或显示 ValidationMessages

如何解决Blazor - 嵌套组件不会突出显示无效字段或显示 ValidationMessages

我不知道如何突出显示无效字段并显示嵌套组件的各个 ValidationMessages。添加页面时相同的代码按预期工作,但是当移动到单独的组件时,页面的 ValidationSummary 显示该组件的错误就好了,但组件本身不提供任何验证结果。

我进行了广泛的搜索,我只找到了关于复杂模型验证的主题,但没有找到关于在嵌套组件中显示验证信息的主题。这表明我可能遗漏了一些简单的东西,但我无法弄清楚这是什么。

这是重现此行为的简化代码

Product.cs

public class Product
{
    public int Id { get; set; }

    [required(ErrorMessage = "Added On Date is required")]
    public DateTime? AddedOn { get; set; }

    [required(ErrorMessage = "Product Name is required")]
    public string Name { get; set; }

    public int BrandId { get; set; }

    public int ManufacturerId { get; set; }
}

ChildComponent.razor

<div class="card">
    <div class="card-header">
        @(new MarkupString(Caption))
    </div>
    <div class="card-body">
        <input type="text" @bind-value=@TextValue />
        <ValidationMessage For=@(() => TextValue) />
        
        <input type="datetime-local" @bind-value=@DateValue />
        <ValidationMessage For=@(() => DateValue) />
    </div>
</div>

@code {
    [Parameter]
    public string Caption { get; set; }

    [Parameter]
    public string TextValue { get; set; }

    [Parameter]
    public DateTime? DateValue { get; set; }
}

TestPage.razor

@page "/test"

<EditForm OnValidSubmit="HandleFormSubmit" Model="@ProductModel">
    <DataAnnotationsValidator />

    @*ValidationMessages are returned/displayed*@
    <div class="card">
        <div class="card-header">
            Control on the Page
        </div>
        <div class="card-body">
            <input type="text" @bind-value=@ProductModel.Name />
            <ValidationMessage For=@(() => ProductModel.Name) />

            <input type="datetime-local" @bind-value=@ProductModel.AddedOn />
            <ValidationMessage For=@(() => ProductModel.AddedOn) />
        </div>
    </div>

    @*ValidationMessages are NOT returned/displayed*@
    <ChildComponent Caption="nested Component"
                    DateValue=@ProductModel.AddedOn
                    TextValue=@ProductModel.Name />

    @*ValidationSummary displays errors as expected*@
    <ValidationSummary />

    <input type="submit" value="Save" class="btn btn-primary" />
</EditForm>

@code {

    Product ProductModel = new Product();

    private async Task HandleFormSubmit(EditContext context) { }
}

编辑:

使用@NeilW 提供的 link 中的信息,我现在可以更改输入控件的 CSS(无效时为红色边框,有效时为绿色),但我仍然无法显示无效控件的 ValidationMessages .有什么建议吗?

enter image description here

解决方法

Chris Sainty 的

Thisthis 篇文章提供了解决方案。感谢 @NeilW 分享链接。

这是按预期工作的更新代码:

Product.cs(无变化)

public class Product
{
    public int Id { get; set; }

    [Required(ErrorMessage = "Added On Date is required")]
    public DateTime? AddedOn { get; set; }

    [Required(ErrorMessage = "Product Name is required")]
    public string Name { get; set; }

    public int BrandId { get; set; }

    public int ManufacturerId { get; set; }
}

ChildComponent.razor

<div class="card">
    <div class="card-header">
        @(new MarkupString(Caption))
    </div>
    <div class="card-body">
        <input type="text" class="@textFieldCss"
            value=@TextValue @oninput="HandleTextInput" />
        @foreach (var message in CascadedEditContext?.GetValidationMessages(textFieldId))
        {
            <div class="validation-message">@message</div>
        }

        <input type="datetime-local" class="@dateFieldCss"
            value=@DateValue @oninput="HandleDateInput" />
        @foreach (var message in CascadedEditContext.GetValidationMessages(dateFieldId))
        {
            <div class="validation-message">@message</div>
        }
    </div>
</div>

@code {
    private FieldIdentifier textFieldId;
    private FieldIdentifier dateFieldId;

    private string textFieldCss => CascadedEditContext?.FieldCssClass(textFieldId) ?? "";
    private string dateFieldCss => CascadedEditContext?.FieldCssClass(dateFieldId) ?? "";

    [CascadingParameter]
    private EditContext CascadedEditContext { get; set; }

    [Parameter]
    public EventCallback<string> TextValueChanged { get; set; }

    [Parameter]
    public EventCallback<DateTime?> DateValueChanged { get; set; }

    [Parameter]
    public System.Linq.Expressions.Expression<Func<string>> TextValueExpression { get; set; }

    [Parameter]
    public System.Linq.Expressions.Expression<Func<DateTime?>> DateValueExpression { get; set; }

    protected override void OnInitialized()
    {
        textFieldId = FieldIdentifier.Create(TextValueExpression);
        dateFieldId = FieldIdentifier.Create(DateValueExpression);
    }

    private async Task HandleTextInput(ChangeEventArgs args)
    {
        await TextValueChanged.InvokeAsync(args.Value.ToString());
        CascadedEditContext?.NotifyFieldChanged(textFieldId);
    }

    private async Task HandleDateInput(ChangeEventArgs args)
    {
        await DateValueChanged.InvokeAsync(args.Value == null
                ? null : Convert.ToDateTime(args.Value));
        CascadedEditContext?.NotifyFieldChanged(dateFieldId);
    }

    [Parameter]
    public string Caption { get; set; }

    [Parameter]
    public string TextValue { get; set; }

    [Parameter]
    public DateTime? DateValue { get; set; }
}

TestPage.razor - 注意添加到组件属性中的 @bind-

@page "/test"

<EditForm Model="@ProductModel">
    <DataAnnotationsValidator />

    <div class="card">
        <div class="card-header">
            Control on the Page
        </div>
        <div class="card-body">
            <input type="text" @bind-value=@ProductModel.Name />
            <ValidationMessage For=@(() => ProductModel.Name) />

            <input type="datetime-local" @bind-value=@ProductModel.AddedOn />
            <ValidationMessage For=@(() => ProductModel.AddedOn) />
        </div>
    </div>

    <ChildComponent Caption="Nested Component"
                    @bind-DateValue=@ProductModel.AddedOn
                    @bind-TextValue=@ProductModel.Name />

    <ValidationSummary />

    <input type="submit" value="Save" class="btn btn-primary" />
</EditForm>

@code {
    Product ProductModel = new Product();
}

结果

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。