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

Blazor组件加载数据后未重新渲染问题求助

问题:Blazor组件未在IsLoaded设为true后重新渲染

我创建了一个绑定供应商长列表的DropDownList组件ContractVendorSelect,代码拆分在ContractVendorSelect.razor和代码后置文件ContractVendorSelect.razor.cs中,并在Test.razor页面引用该组件。当前问题是:当IsLoaded标记设为true(表示供应商列表已获取完成)后,组件始终显示“Loading vendors ...”提示,没有重新渲染出下拉框。我已经尝试在多处调用StateHasChanged()方法,但问题依旧。


相关代码

ContractVendorSelect.razor

<div class="k-form-field-wrap">
    @if (IsLoaded)
    {
        <select @bind=Contract.Vendor>
            <option>-- Select</option>
            @foreach (var item in VendorData)
            {
                <option value="@item.Value">@item.Text</option>
            }
        </select>

    }
    else
    {
        <span>Loading vendors ... </span>
    }
</div>

ContractVendorSelect.razor.cs

public partial class ContractVendorSelect : FormFieldBase
{
    [Parameter]
    public Contract? Contract { get; set; }

    [Parameter]
    public string? Id { get; set; } = null;

    [Parameter]
    public string? Label { get; set; } = null;

    [Parameter]
    public Sites? Site { get; set; } = null;

    protected bool IsLoaded { get; set; } = false;

    internal List<VendorSelectData>? VendorData { get; set; } = new List<StiVendorSelectData>();
    
    private async Task SetVendorList()
    {
        if (Site != null)
        {
            var stagedData = await VendorSearch.GetVendorsAsync(this.Site.DBName);
    
            VendorData = new List<VendorSelectData>();
    
            foreach(Vendor vendor in stagedData)
            {
                VendorData.Add(new VendorSelectData(vendor.Vendor_Name, vendor.Vendor_Key, vendor));
            }
    
            IsLoaded = true;
        }
    }
    
    protected async override Task OnInitializedAsync()
    {
        await this.SetVendorList();
        StateHasChanged();
    }
    
    internal class VendorSelectData
    {
        public long Value { get; set; }
        public String Text { get; set; }
    
        public Vendor Vendor { get; set; }
    
        public VendorSelectData(string text, long value, Vendor model)
        {
            Text = text;
            Value = value;
            Vendor = model;
        }
    }
}

Test.razor

<ContractVendorSelect Id="ddlContractVendor" 
        Label="Vendor" 
        Contract="contract" 
        Site="site">
</ContractVendorSelect>


@code {

    protected Contract contract { get; set; }

    protected Sites site { get; set; }


    public async Task SetContract()
    {
        contract = await ContractSearch.FindContract(<contractID>);
    }

    public async Task SetSite()
    {
        site = await SiteSearch.GetSiteByIDAsync(<SiteID>);
    }


    protected override async Task OnInitializedAsync()
    {
        await SetSite();
        await SetContract();
    }
}

解决方向

1. 修复参数传递的语法错误

在Test.razor中,组件参数绑定缺少@符号,导致传递的是字符串字面量而非变量,组件无法获取到有效的Site和Contract实例:

<ContractVendorSelect Id="ddlContractVendor" 
        Label="Vendor" 
        Contract="@contract" 
        Site="@site">
</ContractVendorSelect>

2. 监听Site参数变化,延迟加载数据

父组件Test.razor的OnInitializedAsync是异步执行的,ContractVendorSelect的OnInitializedAsync可能在site赋值完成前就已执行,导致Site为null,SetVendorList逻辑未触发。重写OnParametersSetAsync方法监听参数变化:

protected override async Task OnParametersSetAsync()
{
    if (Site != null && !IsLoaded)
    {
        await SetVendorList();
        // 异步方法完成后Blazor会自动触发渲染,无需手动调用StateHasChanged
    }
}

同时移除OnInitializedAsync中的SetVendorList调用,避免初始化时因Site为空导致逻辑失效。

3. 修正VendorData初始化的类型错误

代码中VendorData初始化时使用了错误的泛型类型StiVendorSelectData,与定义的List<VendorSelectData>不匹配,修正为:

internal List<VendorSelectData>? VendorData { get; set; } = new List<VendorSelectData>();

4. 验证异步操作执行状态

在SetVendorList中添加日志输出,确认数据是否成功加载、IsLoaded是否被正确设置:

private async Task SetVendorList()
{
    if (Site != null)
    {
        Console.WriteLine("开始加载供应商数据");
        var stagedData = await VendorSearch.GetVendorsAsync(this.Site.DBName);
        Console.WriteLine($"加载完成,共{stagedData.Count}条数据");
    
        VendorData = new List<VendorSelectData>();
        foreach(Vendor vendor in stagedData)
        {
            VendorData.Add(new VendorSelectData(vendor.Vendor_Name, vendor.Vendor_Key, vendor));
        }
    
        IsLoaded = true;
        Console.WriteLine($"IsLoaded已设为{IsLoaded}");
    }
    else
    {
        Console.WriteLine("Site参数为空,跳过数据加载");
    }
}

内容的提问来源于stack exchange,提问作者Gary O. Stenstrom

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:22:45