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

Blazor从组件列表渲染动态元素无显示问题排查

Blazor组件未渲染问题排查

问题概述

在Blazor项目中,尝试通过foreach循环渲染DocumentUploader组件,初始化时向列表添加了组件实例,但页面无任何内容显示,也未抛出错误。

相关代码片段

页面Razor代码

@foreach (var documentUploader in documentUploaderElements)
{
    <documentUploader />
}

页面初始化代码

protected override void OnInitialized()
{
    var doc = new QT_Tagger.Shared.Details.DocumentUploader();
    documentUploaderElements.Add(doc);
    StateHasChanged();

    base.OnInitialized();
}

列表定义

private List<QT_Tagger.Shared.Details.DocumentUploader> documentUploaderElements = new List<Shared.Details.DocumentUploader>();

DocumentUploader组件完整代码

@inject IJSRuntime JsRuntime
@inject NavigationManager NavManager

<div style="margin-top: 10px; width: 80%" >
    <strong style="margin-top: 20px">Dokumenten-Titel*</strong>
    <p>Zur Anzeige auf der Artikelseite</p>
    <input @bind="Title" style="margin-top: 10px;" type="text" maxlength="80" placeholder="Titel: z.B: Original Rechung 01.01.2020">
    <div class="form-group" style="margin-top: 10px; margin-bottom: 10px">
        <strong class="headlines_options">Art des Dokuments</strong>
        <select id="selectedOption" style="margin-top: 10px; color: black; font-size: 13px; max-width: 80%"  class="form-control" @bind="TypeOfResell">
            <option selected style="color: black; font-size: 13px" value="@DocumentTypes.Rechnung"><strong>Rechnung</strong></option>
            <option style="color: black; font-size: 13px" value="@DocumentTypes.Garantie"><strong>Garantie</strong></option>
            <option style="color: black; font-size: 13px" value="@DocumentTypes.Andere"><strong>Andere</strong></option>
        </select>
    </div>
    <InputFile OnChange="@SingleUpload" class="custom-input-file" />
</div>

@code {
    private string Title = "";
    private string TypeOfResell = DocumentTypes.Rechnung.ToString();

    private async Task SingleUpload(InputFileChangeEventArgs e)
    {
        MemoryStream ms = new MemoryStream();
        await e.File.OpenReadStream().CopyToAsync(ms);
        var bytes = ms.ToArray();
        //do something with bytes
    }

    protected override void OnInitialized()
    {
        base.OnInitialized();
    }

    enum DocumentTypes
    {
        Rechnung,
        Garantie,
        Andere
    }
}

错误原因

  1. 组件实例管理错误:Blazor组件的实例由框架负责创建和管理,手动new组件实例并添加到列表的方式完全无效,框架不会识别这些手动创建的实例,也不会将其渲染到页面。
  2. 组件标签命名不规范:Blazor组件标签需要遵循HTML的kebab-case命名规则,PascalCase的组件名DocumentUploader应转换为<document-uploader />(也可直接使用<DocumentUploader />,但kebab-case更符合HTML规范),原代码中的<documentUploader />不符合命名规范,可能导致框架无法识别组件。

解决方案

方案1:仅控制组件渲染数量(无数据绑定需求)

如果只是需要渲染固定数量的DocumentUploader组件,无需存储组件实例,直接用计数变量控制循环即可:

  • 修改列表定义为计数变量:
private int uploaderCount = 0;
  • 初始化时设置计数:
protected override void OnInitialized()
{
    uploaderCount = 1; // 需要渲染的组件数量
    base.OnInitialized();
}
  • 修改Razor循环代码:
@for (int i = 0; i < uploaderCount; i++)
{
    <document-uploader />
}

方案2:绑定组件数据(有数据交互需求)

如果需要为每个组件传递或管理数据,应创建数据模型而非存储组件实例:

  • 创建组件对应的数据模型:
public class DocumentUploaderModel
{
    public string Title { get; set; } = "";
    public string TypeOfResell { get; set; } = "Rechnung";
}
  • 修改列表定义为数据模型列表:
private List<DocumentUploaderModel> uploaderModels = new();
  • 初始化时添加数据模型:
protected override void OnInitialized()
{
    uploaderModels.Add(new DocumentUploaderModel());
    base.OnInitialized();
}
  • 修改DocumentUploader组件,添加参数接收数据模型:
@inject IJSRuntime JsRuntime
@inject NavigationManager NavManager

<div style="margin-top: 10px; width: 80%" >
    <strong style="margin-top: 20px">Dokumenten-Titel*</strong>
    <p>Zur Anzeige auf der Artikelseite</p>
    <input @bind="Model.Title" style="margin-top: 10px;" type="text" maxlength="80" placeholder="Titel: z.B: Original Rechung 01.01.2020">
    <div class="form-group" style="margin-top: 10px; margin-bottom: 10px">
        <strong class="headlines_options">Art des Dokuments</strong>
        <select id="selectedOption" style="margin-top: 10px; color: black; font-size: 13px; max-width: 80%"  class="form-control" @bind="Model.TypeOfResell">
            <option selected style="color: black; font-size: 13px" value="@DocumentTypes.Rechnung"><strong>Rechnung</strong></option>
            <option style="color: black; font-size: 13px" value="@DocumentTypes.Garantie"><strong>Garantie</strong></option>
            <option style="color: black; font-size: 13px" value="@DocumentTypes.Andere"><strong>Andere</strong></option>
        </select>
    </div>
    <InputFile OnChange="@SingleUpload" class="custom-input-file" />
</div>

@code {
    [Parameter]
    public DocumentUploaderModel Model { get; set; } = new();

    private async Task SingleUpload(InputFileChangeEventArgs e)
    {
        MemoryStream ms = new MemoryStream();
        await e.File.OpenReadStream().CopyToAsync(ms);
        var bytes = ms.ToArray();
        //do something with bytes
    }

    enum DocumentTypes
    {
        Rechnung,
        Garantie,
        Andere
    }
}
  • 修改页面Razor循环代码,传递数据模型:
@foreach (var model in uploaderModels)
{
    <document-uploader Model="model" />
}

额外说明

  • 无需在OnInitialized中手动调用StateHasChanged(),框架会在初始化完成后自动触发组件渲染。
  • Blazor组件的渲染完全由框架控制,开发者只需通过Razor标签声明组件,并通过参数传递数据,无需手动管理组件实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 13:48:11