Blazor 7下拉组件选中项传递异常:父组件仅获前一次选中值
问题分析与解决方案
问题根源
- 渲染顺序导致旧值传递:你在组件的渲染模板中(
@if (mySelector.SelectedId > 0)块)给selectedOption赋值,但Blazor中@bind:after触发的SelectionChanged事件会先于模板渲染更新执行,此时selectedOption还是上一次的旧值,所以父组件收到的总是滞后一步的结果。 - 异步回调方式错误:
SelectionChanged使用async void定义,这在Blazor中可能引发UI更新不同步问题,规范写法应使用async Task处理异步事件回调。
修复后的子组件代码
<h3>DropDownNames</h3> <select @bind="@mySelector.SelectedId" @bind:after="SelectionChanged"> @foreach (var opt in mySelector.Options) { <option value="@opt.Id" class="@opt.Style">@opt.Name @(new String('*', @opt.Stars))</option> } </select> @code { [Parameter] public EventCallback<Option> GetSelectedOption { get; set; } private Selector mySelector = new Selector(myOptions); // 下拉选项数据源 private static List<Option> myOptions = new List<Option>() { new Option(1, "Fred", "style3", 2), new Option(2, "Joe", "style1", 4), new Option(3, "Jana", "style2", 4), new Option(4, "Mary", "style1", 3), new Option(5, "Howard", "style3", 1) }; // 改为async Task,符合Blazor异步回调规范 async Task SelectionChanged() { // 直接在回调中获取最新选中项,不再依赖渲染块赋值 var selectedOption = mySelector.SelectedId > 0 ? mySelector.Options.Find(e => e.Id == mySelector.SelectedId) : new Option(); await GetSelectedOption.InvokeAsync(selectedOption); } public class Selector { public Selector(List<Option> options) => Options = options; public int SelectedId { get; set; } = 0; public List<Option> Options { get; set; } } public class Option { public Option(int id = 0, string? name = "", string? style = "", int stars = 0) { Id = id; Name = name; Style = style; Stars = stars; } public int Id { get; set; } public string? Name { get; set; } public string? Style { get; set; } public int Stars { get; set; } } }
修复后的父页面代码
@page "/" <PageTitle>Index</PageTitle> <DropDownNames GetSelectedOption="getSelectedOption"></DropDownNames> <br /> <p>You selected: @selectedOption.Id</p> <p>@selectedOption.Name has @selectedOption.Stars.ToString() stars</p> @code { DropDownNames.Option selectedOption = new DropDownNames.Option(); public void getSelectedOption(DropDownNames.Option option) { selectedOption = option; // 显式通知UI更新,确保状态变更及时生效 StateHasChanged(); } }
关键修改说明
- 移除渲染模板中对
selectedOption的赋值逻辑,改为在SelectionChanged回调内直接获取最新选中项,确保传递给父组件的是当前最新值。 - 将
async void改为async Task,遵循Blazor异步事件处理的最佳实践,避免UI更新异常。 - 父组件中添加
StateHasChanged()显式触发UI刷新,确保选中状态变更能及时在页面上展示。
内容的提问来源于stack exchange,提问作者MC9000
相关产品推荐
相关产品推荐

