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

Blazor DynamicComponent点击事件获取对应行数据实现方案

Blazor动态组件表格行数据获取方案

通过TableTemplate自动注入行上下文的方式即可实现点击按钮时获取对应行的宠物名,该方案复用性最高,不需要业务页面重复传参,以下是完整实现步骤:


步骤1:修正基础定义错误

  • 调整ComponentMetadata类:原类中存储组件类型的Name属性为字符串类型,和DynamicComponent要求的Type类型参数不匹配,直接修改为存储Type类型,避免字符串解析类型的加载问题:
public class ComponentMetadata
{
    // 原Name属性改为ComponentType,直接存组件类型
    public Type? ComponentType { get; set; }
    public Dictionary<string, object> Parameters { get; set; } = 
        new Dictionary<string, object>();
}
  • 调整MyButton组件:原组件点击方法默认接收的是Blazor注入的MouseEventArgs鼠标事件参数,无法直接拿到行数据,新增行上下文参数存储关联数据,点击时回传即可:
<button type="button"
        class="@Style"
        @onclick="BtnClick">
@Text
</button>

@code {
    [Parameter]
    public string Style { get; set; }
    [Parameter]
    public string Text { get; set; }
    // 新增:存储当前行关联的业务数据
    [Parameter]
    public object? RowContext { get; set; }
    [Parameter]
    public EventCallback<object> OnBtnClick { get; set; }

    private async Task BtnClick() 
    {
        // 点击时回传关联的行数据
        await OnBtnClick.InvokeAsync(RowContext!);
    }
}

步骤2:修改TableTemplate自动注入行数据

在遍历行配置渲染动态组件时,由表格组件自动把当前行的DataItem注入到动态组件的参数中,不需要业务页面手动绑定,避免漏传:

<table class="table">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @foreach (var RowTemplateConfig in RowTemplateConfigs)
        {
            if (RowTemplateConfig.DataItem is not null)
            {
                <tr>
                  <td> @RowTemplateConfig.DataItem </td>
                 
                 @if(RowTemplateConfig.ComponentMetadata is not null)
                 {
                  <td>
                    <DynamicComponent
                     Type="@RowTemplateConfig.ComponentMetadata.ComponentType"
                     Parameters="@GetMergedParameters(RowTemplateConfig)" />
                  </td>
                 }
               </tr>
           }
       }
    </tbody>
</table>

@code {
    public class RowTemplateConfig 
    {
      public ComponentMetadata ComponentMetadata { get; set;} = new();
      public string DataItem { get; set; } = string.Empty;
    }
    [Parameter]
    public RenderFragment? TableHeader { get; set; }

    [Parameter]
    public List<RowTemplateConfig> RowTemplateConfigs {get; set;} = new();

    // 合并原有参数和自动注入的行上下文
    private Dictionary<string, object> GetMergedParameters(RowTemplateConfig rowConfig)
    {
        var paramDict = new Dictionary<string, object>(rowConfig.ComponentMetadata.Parameters);
        // 约定参数名为RowContext,所有需要拿行数据的动态组件都定义同名参数即可
        paramDict["RowContext"] = rowConfig.DataItem;
        return paramDict;
    }
}

注意:原代码中TableTemplate标签上写的TItem =string没有对应的泛型定义,会编译报错,直接删除即可。


步骤3:调整业务页面代码

修正原配置初始化的语法错误(字典项缺逗号、typeof写法不完整),回调中直接拿传入的行数据即可:

@page "/pets1"

<h1>Pets</h1>

<TableTemplate RowTemplateConfigs="@RowTemplateConfigs">
    <TableHeader>
        <th>Name</th>
        <th>Operation</th>
    </TableHeader>
</TableTemplate>

@code {
    private List<RowTemplateConfig> RowTemplateConfigs = new()
    {
        new RowTemplateConfig() 
        {
          DataItem = "Bigglesworth",
          ComponentMetadata = new()
          {
           ComponentType = typeof(MyButton),
           Parameters = new Dictionary<string, object>()
           {
            { nameof(MyButton.Style), "btn btn-outline-success" },
            { nameof(MyButton.OnBtnClick),  EventCallback.Factory.Create<object>(this, OnTestClick)},
            { nameof(MyButton.Text), "Hi"}
           }
          }
        },
        new RowTemplateConfig() 
        {
          DataItem = "Saberhagen",
          ComponentMetadata = new()
          {
           ComponentType = typeof(MyButton),
           Parameters = new Dictionary<string, object>()
           {
            { nameof(MyButton.Style), "btn btn-outline-success" },
            { nameof(MyButton.OnBtnClick),  EventCallback.Factory.Create<object>(this, OnTestClick)},
            { nameof(MyButton.Text), "Hi"}
           }
          }
        },
    };

    private async Task OnTestClick(object rowData)
    {
        // 这里拿到的就是点击按钮对应行的宠物名称
        string currentPetName = (string)rowData;
        // 后续业务逻辑直接用currentPetName即可
        await Task.CompletedTask;
    }
}

备选轻量方案(无需修改TableTemplate)

如果不想调整表格组件逻辑,可以在初始化每一行配置时,通过C#闭包直接捕获当前行的DataItem,绑定专属回调:

new RowTemplateConfig() 
{
    DataItem = "Bigglesworth",
    ComponentMetadata = new()
    {
        ComponentType = typeof(MyButton),
        Parameters = new Dictionary<string, object>()
        {
            { nameof(MyButton.Style), "btn btn-outline-success" },
            // 闭包捕获当前DataItem,点击时直接传入
            { nameof(MyButton.OnBtnClick),  EventCallback.Factory.Create<MouseEventArgs>(this, () => OnTestClick("Bigglesworth"))},
            { nameof(MyButton.Text), "Hi"}
        }
    }
}

对应的回调方法直接接收string类型参数即可,缺点是动态数据场景下需要手动为每一项绑定值,容易出错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:02:15