如何让带有预选中值的FluentSelect表单验证通过?
问题:Blazor FluentUI预选中值的FluentSelect表单提交时验证失败
我正在使用Blazor搭配FluentUI(v4.11.8)库开发支持实体新建与编辑的表单。当加载带有预选中值的FluentSelect表单并尝试提交时,框架返回提示:“Please select an item in the list”,仿佛没有选中任何内容。
可复现示例代码
Home.razor
@page "/" @rendermode InteractiveServer @inject NavigationManager Navigation <PageTitle>Home</PageTitle> <FluentNumberField Label="Fill with existing id from 1 to 3" @bind-Value="Id" /> <FluentButton OnClick="@(() => Navigation.NavigateTo($"edit/{Id}"))"> Edit or Create </FluentButton> @code { public int? Id { get; set; } }
FormComponent.razor
@page "/edit/{Id:int?}" @rendermode InteractiveServer <PageTitle>Form Component</PageTitle> <EditForm FormName="theform" Model="@study" OnValidSubmit="@HandleValidSubmit"> <FluentSelect Required="true" Items="@studies" OptionText="@(o => o.Text)" OptionValue="@(o => o.Value!.Name)" @bind-Value="selectedStudy"/> <FluentButton Appearance="Appearance.Accent" Type="ButtonType.Submit"> Submit </FluentButton> </EditForm> @code { [Parameter] public int? Id { get; set; } private List<Option<Study>> studies = new List<Option<Study>> { new Option<Study>(){ Value = new Study { Id = 1, Name = "Study 1" }, Text = "Study 1"}, new Option<Study>(){ Value = new Study { Id = 2, Name = "Study 2" }, Text = "Study 2"}, new Option<Study>(){ Value = new Study { Id = 3, Name = "Study 3" }, Text = "Study 3"} }; private string? selectedStudy; private Study study = new Study(); protected override void OnInitialized() { if (Id.HasValue) { selectedStudy = studies.Single(study => study.Value!.Id == Id.Value).Value!.Name; } } private void HandleValidSubmit() { } public class Study { public int Id { get; set; } public string Name { get; set; } = string.Empty; } }
问题原因
核心问题在于**selectedStudy是独立字段,不属于EditForm绑定的Model(即study对象)**,导致EditContext(表单验证上下文)无法跟踪该字段的变化。初始时selectedStudy为null,触发了Required验证;后续在OnInitialized中设置了值,但EditContext未感知到这个变更,因此验证状态仍停留在“未选中”的无效状态。
解决方案
方案一:将选中值绑定到Model属性(推荐)
把FluentSelect的绑定目标改为Model的属性,让EditContext自动跟踪字段变化:
修改FormComponent.razor的代码:
- 移除独立的
selectedStudy字段 - 将
FluentSelect的@bind-Value改为绑定study.Name - 在
OnInitialized中直接设置study.Name
修改后的FormComponent.razor关键部分:
<EditForm FormName="theform" Model="@study" OnValidSubmit="@HandleValidSubmit"> <FluentSelect Required="true" Items="@studies" OptionText="@(o => o.Text)" OptionValue="@(o => o.Value!.Name)" @bind-Value="study.Name"/> <!-- 按钮部分不变 --> </EditForm> @code { // 移除 private string? selectedStudy; protected override void OnInitialized() { if (Id.HasValue) { study.Name = studies.Single(study => study.Value!.Id == Id.Value).Value!.Name; } } // 其他代码不变 }
方案二:手动通知EditContext字段变更(保留独立字段场景)
如果必须保留独立的selectedStudy字段,需要在设置值后手动通知EditContext更新验证状态:
- 给
EditForm添加@ref引用 - 在设置
selectedStudy后,触发字段变更通知并重新验证
修改后的FormComponent.razor关键部分:
<EditForm @ref="editForm" FormName="theform" Model="@study" OnValidSubmit="@HandleValidSubmit"> <!-- FluentSelect和按钮部分不变 --> </EditForm> @code { private EditForm? editForm; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && Id.HasValue) { selectedStudy = studies.Single(study => study.Value!.Id == Id.Value).Value!.Name; if (editForm?.EditContext != null) { // 通知EditContext字段已变更 var fieldId = FieldIdentifier.Create(() => selectedStudy); editForm.EditContext.NotifyFieldChanged(fieldId); // 重新触发验证 editForm.EditContext.Validate(); // 更新UI显示验证状态 StateHasChanged(); } } await base.OnAfterRenderAsync(firstRender); } // 其他代码不变 }
验证效果
修改后,进入编辑状态时FluentSelect的预选中值会被EditContext正确识别,提交表单时不再出现“Please select an item in the list”的错误提示,验证可正常通过。
内容的提问来源于stack exchange,提问作者E.Benedos
相关产品推荐
相关产品推荐

