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

Blazor中FormItem基于if条件无法重新显示的问题

解决方案

问题根源

你遇到的问题本质是:当用@if(HasCinema)销毁FormItem组件后,再次渲染时Telerik Form的内部状态未正确同步,导致组件无法重建;而添加else块会插入额外元素打乱FormItem的固有顺序。


方案1:CSS控制显示隐藏(推荐,无缝无顺序问题)

通过display属性控制FormItem的显示/隐藏,组件始终保留在DOM中,不会被销毁重建,既保证顺序不变,又实现无缝切换:

<TelerikForm Model="@Model">
    <FormItems>
        <FormItem Field="@nameof(Model.City)">
            <Template>
                <TelerikRadioGroup @bind-Value="@Model.City" OnChange="@OnCityChanged">
                    @foreach (var city in Enum.GetValues<City>())
                    {
                        <RadioGroupItem Value="@city" />
                    }
                </TelerikRadioGroup>
            </Template>
        </FormItem>

        <!-- 用CSS控制显示隐藏,保留DOM位置 -->
        <FormItem Field="@nameof(Model.CinemaName)"
                  Style="@(HasCinema ? "display:block;" : "display:none;")">
        </FormItem>

        <!-- 其他FormItem正常排列 -->
        <FormItem Field="@nameof(Model.OtherInfo)" />
    </FormItems>
</TelerikForm>

@code {
    public MyModel Model { get; set; } = new MyModel();
    public bool HasCinema { get; set; }

    protected override void OnInitialized()
    {
        UpdateHasCinema();
    }

    private void OnCityChanged(object value)
    {
        Model.City = (City)value;
        UpdateHasCinema();
    }

    private void UpdateHasCinema()
    {
        // 根据枚举值判断是否显示影院字段
        HasCinema = Model.City switch
        {
            City.Beijing => true,
            City.Shanghai => true,
            _ => false
        };
    }

    public enum City
    {
        Beijing,
        Shanghai,
        Guangzhou
    }

    public class MyModel
    {
        public City City { get; set; }
        public string CinemaName { get; set; }
        public string OtherInfo { get; set; }
    }
}

方案2:强制Form重新渲染(适合必须销毁组件的场景)

如果必须用@if逻辑销毁组件,给Telerik Form添加@key属性,当HasCinema变化时强制Form重新渲染,确保FormItem正确重建且顺序不变:

<TelerikForm Model="@Model" @key="@HasCinema">
    <FormItems>
        <FormItem Field="@nameof(Model.City)">
            <Template>
                <TelerikRadioGroup @bind-Value="@Model.City" OnChange="@OnCityChanged">
                    @foreach (var city in Enum.GetValues<City>())
                    {
                        <RadioGroupItem Value="@city" />
                    }
                </TelerikRadioGroup>
            </Template>
        </FormItem>

        @if (HasCinema)
        {
            <FormItem Field="@nameof(Model.CinemaName)">
            </FormItem>
        }

        <FormItem Field="@nameof(Model.OtherInfo)" />
    </FormItems>
</TelerikForm>

方案说明

  • 方案1性能更优:组件无需销毁重建,仅通过CSS切换显示状态,完全避免顺序混乱和渲染异常。
  • 方案2通过@key触发Form整体重建,强制同步内部状态,适合有特殊业务需要必须销毁组件的场景。

内容的提问来源于stack exchange,提问作者ISquared

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:28:31