如何使用mat-table将用户的多个角色分多行展示
问题描述
我想用mat-table展示用户数据,要求Role列中每个用户的多个roleName单独占一行。API返回的用户数据格式如下:
[ { "firstName": "User", "lastName": "1", "roles": [ {"id": "1", "roleName": "first Role"}, {"id": "2", "roleName": "second Role"} ] }, { "firstName": "User", "lastName": "2", "roles": [ {"id": "1", "roleName": "third Role"}, {"id": "2", "roleName": "fourth Role"} ] } ]
尝试在mat-cell中用*ngFor遍历角色时出现报错,最终想要实现的表格效果如下:
| firstName | lastName | Role |
|---|---|---|
| User | 1 | first Role |
| User | 1 | second Role |
| User | 2 | third Role |
| User | 2 | fourth Role |
解决方案
直接在mat-cell嵌套*ngFor会破坏mat-table的行结构导致报错,正确做法是先扁平化处理数据源,将每个用户的每个角色转换为独立的表格行数据,再交给mat-table渲染。
1. 数据预处理(user.component.ts)
获取API数据后,拆解用户数据为角色维度的数组:
import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MatTableDataSource } from '@angular/material/table'; // 原始用户数据结构 interface User { firstName: string; lastName: string; roles: { id: string; roleName: string }[]; } // 扁平化后的表格行数据结构 interface UserRoleRow { firstName: string; lastName: string; roleName: string; } @Component({ selector: 'app-user', templateUrl: './user.component.html', styleUrls: ['./user.component.css'] }) export class UserComponent implements OnInit { displayedColumns: string[] = ['firstName', 'lastName', 'role']; dataSource = new MatTableDataSource<UserRoleRow>([]); constructor(private http: HttpClient) {} ngOnInit(): void { this.http.get<User[]>('你的API接口地址').subscribe(users => { // 扁平化数据:将每个用户的每个角色转为单独行 const flattenedRows: UserRoleRow[] = users.flatMap(user => user.roles.map(role => ({ firstName: user.firstName, lastName: user.lastName, roleName: role.roleName })) ); this.dataSource.data = flattenedRows; }); } }
2. 模板代码(user.component.html)
直接渲染扁平化后的数据源,无需嵌套循环:
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8"> <!-- firstName列定义 --> <ng-container matColumnDef="firstName"> <th mat-header-cell *matHeaderCellDef> firstName </th> <td mat-cell *matCellDef="let element"> {{element.firstName}} </td> </ng-container> <!-- lastName列定义 --> <ng-container matColumnDef="lastName"> <th mat-header-cell *matHeaderCellDef> lastName </th> <td mat-cell *matCellDef="let element"> {{element.lastName}} </td> </ng-container> <!-- Role列定义 --> <ng-container matColumnDef="role"> <th mat-header-cell *matHeaderCellDef> Role </th> <td mat-cell *matCellDef="let element"> {{element.roleName}} </td> </ng-container> <!-- 表头行 --> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <!-- 数据行 --> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table>
内容的提问来源于stack exchange,提问作者Satyam Patel
相关产品推荐
相关产品推荐

