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

Angular 8中MatTable如何获取选中行的单个ID?

解决Angular MatTable点击行获取id的报错问题

看起来你遇到的核心问题是参数类型不匹配+数据源结构混淆,导致无法正确获取选中行的id,下面一步步帮你解决:

1. 先修正最直接的错误:参数类型不匹配

你当前代码里的矛盾点很明显:

  • HTML中传递的是row.id(这是一个字符串,或者如果row不是EcheqDefinitionApi的话,可能是undefined)
  • 但TS函数getRowId的参数类型定义为EcheqDefinitionApi,然后你尝试访问rowId.id——这就相当于在一个字符串/undefined上找id属性,必然会报Cannot read property 'id' of undefined的错误。

2. 明确你的数据源结构

你提到用reduce按family分组生成了ListItem数组作为MatTable的数据源,首先得明确ListItem的结构(你没贴出来,我根据场景做合理推断):
假设你的分组逻辑是把同family的EcheqDefinitionApi包装成一个ListItem,结构大概是这样:

interface ListItem {
  family: string;
  echeqItem: EcheqDefinitionApi; // 每个ListItem包裹一个单个的Echeq对象
}

或者是分组后包含多个同family的对象:

interface ListItem {
  family: string;
  echeqItems: EcheqDefinitionApi[]; // 一个family下的所有Echeq对象集合
}

3. 根据数据源结构调整代码

情况一:ListItem是单个Echeq的包裹对象

如果你的表格每一行对应一个ListItem(也就是一个EcheqDefinitionApi),那修改如下:

  • HTML部分:传递正确的属性
<ng-container matColumnDef="dupliceren">
  <th mat-header-cell *matHeaderCellDef i18n>duplicate</th>
  <td mat-cell *matCellDef="let row">
    <!-- 直接传递包裹的Echeq对象的id,或者整个对象 -->
    <a mat-button mat-icon-button (click)="getRowId(row.echeqItem.id)" >
      <mat-icon>filter_none</mat-icon>
    </a >
  </td>
</ng-container>
  • TS部分:匹配参数类型
// 直接接收id字符串
getRowId(rowId: string) {
  console.log(rowId); // 这里就能拿到你想要的id,比如e38e3a37-eda5-4010-d656-08d81c0f3353
}

如果你想传递整个Echeq对象以便后续使用其他字段,也可以这么写:

  • HTML:
<a mat-button mat-icon-button (click)="getRowId(row.echeqItem)" >
  • TS:
getRowId(echeq: EcheqDefinitionApi) {
  console.log(echeq.id);
}

情况二:ListItem是分组后的多对象集合(展开行场景)

如果你的表格是「分组父行+展开子行」的结构,父行显示family,子行显示该family下的所有Echeq,那需要确保点击的是子行里的具体Echeq项:

  • HTML(示例展开行结构):
<!-- 分组父行 -->
<tr mat-row *matRowDef="let row; columns: displayedColumns;" 
    matRipple 
    class="element-row" 
    [class.expanded]="expandedElement === row"
    (click)="expandedElement = expandedElement === row ? null : row">
</tr>
<!-- 展开的子行,展示该family下的所有Echeq -->
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="detail-row">
  <td colspan="999">
    <div class="example-element-detail">
      <!-- 遍历分组里的所有Echeq,每个项对应一个按钮 -->
      <div *ngFor="let echeq of row.echeqItems">
        <a mat-button mat-icon-button (click)="getRowId(echeq.id)" >
          <mat-icon>filter_none</mat-icon>
        </a>
        {{echeq.title}}
      </div>
    </div>
  </td>
</tr>
  • TS部分同样用接收字符串id的函数即可。

4. 额外排查点

  • 先在构造函数里打印this.dataSource.data,确认数据源的每一项确实包含有效的id字段,避免分组的reduce逻辑错误导致id丢失。
  • 如果你的ListItem是直接从EcheqDefinitionApi扩展而来(分组时只是添加了family标识),那直接用row.id即可,但要确保TS函数参数类型匹配(比如接收string类型)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 10:07:32