You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 01:27:17