Blazor绑定父子下拉控件时子控件默认值无法正常显示
问题根因
这是Blazor原生select元素绑定的渲染时序问题:
- 父下拉框值变更时,在
CountryName的setter中会同时替换子下拉框的数据源Zones、修改子下拉框的绑定值ZoneName - Blazor渲染时会先更新子下拉框的option列表,此时新的option集合还未和新的
ZoneName做匹配,后续的选中值同步逻辑会被组件diff优化跳过 - 最终表现为绑定值本身更新正确(页面标签能正常显示),但下拉框视觉上是空白状态。
修复方法
最小改动方案是给子下拉框添加@key属性,绑定当前选中的父级值,强制父选项变更时子下拉框整体重渲染,绕开diff逻辑的匹配bug,不需要改动原有业务逻辑。
修正后完整代码
@page "/test" <select @bind="@CountryName"> @foreach (var country in Countries) { <option>@country.Name</option> } </select> <!-- 新增@key绑定父级选中值即可解决问题 --> <select @bind="@ZoneName" @key="@CountryName"> @foreach (string zone in Zones) { <option>@zone</option> } </select> <div>Selected country: @CountryName</div> <div>Selected zone: @ZoneName</div> @code { private List<Country> Countries; private List<String> Zones = new(); private string countryName; private string CountryName { get => countryName; set { countryName = value; var country = Countries.First(x => x.Name == value); Zones = country.Zones.Select(x => x.Name).ToList(); ZoneName = country.DefaultZoneName; } } private string zoneName; private string ZoneName { get => zoneName; set { zoneName = value; } } protected override void OnInitialized() { //测试数据初始化 var barcelona = new Zone() { Name = "Barcelona" }; var madrid = new Zone() { Name = "Madrid" }; var spain = new Country() { Name = "Spain" }; spain.Zones.Add(barcelona); spain.Zones.Add(madrid); spain.DefaultZoneName = spain.Zones.Last().Name; var açores = new Zone() { Name = "Açores" }; var algarve = new Zone() { Name = "Algarve" }; var portugal = new Country() { Name = "Portugal" }; portugal.Zones.Add(açores); portugal.Zones.Add(algarve); portugal.DefaultZoneName = portugal.Zones.Last().Name; Countries = new List<Country>(); Countries.Add(spain); Countries.Add(portugal); CountryName = Countries.Last().Name; } //数据模型 public class Country { public string Name { get; set; } public List<Zone> Zones { get; set; } = new(); public string DefaultZoneName { get; set; } } public class Zone { public string Name { get; set; } } }
其他可选修复方式:将
ZoneName的赋值逻辑放到异步延迟回调中,等待option列表渲染完成后再赋值,但这种写法冗余度高,不如加@key的方案稳定。
内容的提问来源于stack exchange,提问作者Matias Masso
相关产品推荐
相关产品推荐

