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
相关产品推荐
相关产品推荐

