如何解决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 .有什么建议吗?
解决方法
Chris Sainty 的
This 和 this 篇文章提供了解决方案。感谢 @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();
}
结果
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。