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

如何使用string.Format处理Blazor中的@ref以简化下拉项代码

问题

我有大量重复的Blazor下拉项代码,示例如下:

@if (ItemTest.Contains("One"))
{
    <li class="dropdown-item">
        <button @ref="_btn1" class="item" id="0" @onclick=Open1>One</button>
    </li>
    <li class="dropdown-item">
        <button @ref="_btn2" class="item" id="1" @onclick=Open2>Two</button>
    </li>
} 
                        
@if (ItemTest.Contains("Two"))
{
    <li class="dropdown-item">
        <button @ref="_btn3" class="item" id="3" @onclick=Open3>Three</button>
    </li>
}

我想重写代码以减少行数,提升可读性和可维护性,请问如何用string.Format来处理@ref?

解答

首先要明确:Blazor的@ref是编译时指令,无法通过string.Format这类字符串拼接方式动态生成——因为字符串渲染后仅为静态文本,Blazor不会解析其中的指令绑定。要优化这类重复代码,更合理的方案是通过「数据驱动+组件复用」实现:

步骤1:定义下拉项数据模型

把每个按钮的关键参数封装成类,统一管理配置:

public class DropdownItem
{
    public string ShowKey { get; set; } // 用于判断是否显示的标识(对应原代码的"One"/"Two")
    public string DisplayText { get; set; } // 按钮显示文本
    public string ButtonId { get; set; } // 按钮ID
    public Action ClickHandler { get; set; } // 点击事件逻辑
}

步骤2:初始化数据集合与引用存储容器

在组件代码块中,把所有下拉项的配置统一存入集合,同时用字典替代零散的_btn1/_btn2变量存储按钮引用:

private List<DropdownItem> _dropdownConfigs = new()
{
    new DropdownItem { ShowKey = "One", DisplayText = "One", ButtonId = "0", ClickHandler = Open1 },
    new DropdownItem { ShowKey = "One", DisplayText = "Two", ButtonId = "1", ClickHandler = Open2 },
    new DropdownItem { ShowKey = "Two", DisplayText = "Three", ButtonId = "3", ClickHandler = Open3 },
};

private Dictionary<string, ElementReference> _buttonRefs = new();

步骤3:循环渲染下拉项

用循环替代重复的@if和HTML代码,通过字典绑定@ref:

@foreach (var item in _dropdownConfigs.Where(i => ItemTest.Contains(i.ShowKey)))
{
    <li class="dropdown-item">
        <button 
            @ref="@(_buttonRefs[item.ButtonId])" 
            class="item" 
            id="@item.ButtonId" 
            @onclick="item.ClickHandler">
            @item.DisplayText
        </button>
    </li>
}

为什么不推荐用string.Format?

  • string.Format生成的是HTML字符串,Blazor默认会转义特殊字符;即使强制渲染为HTML(@((MarkupString)formattedContent)),@ref也不会被Blazor识别,无法完成组件引用绑定。
  • 这种方式会丢失Blazor的类型安全和编译时检查,增加调试与维护难度。

额外优化:封装独立组件

如果这类下拉项在多个页面复用,可以进一步封装成组件,彻底消除重复代码:

<!-- DropdownItem.razor -->
<li class="dropdown-item">
    <button @ref="ButtonRef" class="item" id="@ButtonId" @onclick="ClickHandler">@DisplayText</button>
</li>

@code {
    [Parameter] public string ButtonId { get; set; }
    [Parameter] public string DisplayText { get; set; }
    [Parameter] public Action ClickHandler { get; set; }
    [Parameter] public ElementReference ButtonRef { get; set; }
}

父组件中使用:

@foreach (var item in _dropdownConfigs.Where(i => ItemTest.Contains(i.ShowKey)))
{
    <DropdownItem 
        ButtonId="@item.ButtonId" 
        DisplayText="@item.DisplayText" 
        ClickHandler="@item.ClickHandler" 
        ButtonRef="@(_buttonRefs[item.ButtonId])" />
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:01:19