Angular 15:如何用Mat-Table/Mat-Expansion Panel实现可展开分组行
Angular Mat-Table 分组行展开功能实现方案
核心思路
通过跟踪分组状态的展开/折叠状态,结合Mat-Table的multiTemplateDataRows属性,控制对应分组下数据行的显示与隐藏。
步骤1:组件类添加状态管理逻辑
在组件TypeScript文件中,添加状态跟踪集合与切换方法:
import { Component } from '@angular/core'; interface Dataset { id: string; name: string; status: string; createdAt: string; } @Component({ selector: 'app-datasets-table', templateUrl: './datasets-table.component.html', styleUrls: ['./datasets-table.component.css'] }) export class DatasetsTableComponent { // 示例原始数据 datasets: Dataset[] = [ { id: '1', name: '数据集A', status: '已完成', createdAt: '2024-01-01' }, { id: '2', name: '数据集B', status: '处理中', createdAt: '2024-01-02' }, { id: '3', name: '数据集C', status: '已完成', createdAt: '2024-01-03' }, { id: '4', name: '数据集D', status: '待处理', createdAt: '2024-01-04' } ]; // 分组后的数据集结构 groupedDatasets: { status: string, items: Dataset[] }[] = []; // 跟踪展开的分组状态 expandedStatuses = new Set<string>(); displayedColumns = ['statusGroup', 'name', 'id', 'createdAt']; ngOnInit() { // 执行分组逻辑 const statusMap = new Map<string, Dataset[]>(); this.datasets.forEach(dataset => { if (!statusMap.has(dataset.status)) { statusMap.set(dataset.status, []); } statusMap.get(dataset.status)!.push(dataset); }); this.groupedDatasets = Array.from(statusMap.entries()).map(([status, items]) => ({ status, items })); } // 切换分组展开状态 toggleExpansion(status: string) { this.expandedStatuses.has(status) ? this.expandedStatuses.delete(status) : this.expandedStatuses.add(status); } // 判断分组是否展开(用于模板条件) isGroupExpanded = (group: { status: string, items: Dataset[] }) => { return this.expandedStatuses.has(group.status); }; }
步骤2:修改HTML模板实现展开交互
给表格添加multiTemplateDataRows属性,配置分组行点击事件与数据行显示条件:
<table mat-table [dataSource]="groupedDatasets" multiTemplateDataRows class="mat-elevation-z8"> <!-- 分组状态列 --> <ng-container matColumnDef="statusGroup"> <th mat-header-cell *matHeaderCellDef> 状态分组 </th> <td mat-cell *matCellDef="let group" (click)="toggleExpansion(group.status)" style="cursor: pointer;"> <mat-icon>{{ expandedStatuses.has(group.status) ? 'expand_less' : 'expand_more' }}</mat-icon> {{ group.status }} ({{ group.items.length }} 条数据) </td> </ng-container> <!-- 数据列定义 --> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef> 数据集名称 </th> <td mat-cell *matCellDef="let element"> {{ element.name }} </td> </ng-container> <ng-container matColumnDef="id"> <th mat-header-cell *matHeaderCellDef> ID </th> <td mat-cell *matCellDef="let element"> {{ element.id }} </td> </ng-container> <ng-container matColumnDef="createdAt"> <th mat-header-cell *matHeaderCellDef> 创建时间 </th> <td mat-cell *matCellDef="let element"> {{ element.createdAt }} </td> </ng-container> <!-- 分组行模板 --> <tr mat-row *matRowDef="let group; columns: ['statusGroup']"></tr> <!-- 数据行模板:仅分组展开时显示 --> <tr mat-row *matRowDef="let group; columns: ['name', 'id', 'createdAt']; when: isGroupExpanded"> </tr> </table>
关键说明
multiTemplateDataRows:允许Mat-Table同时使用分组行、数据行两种模板expandedStatuses集合:通过Set高效管理展开状态,避免重复状态存储- 分组行点击事件:触发状态切换,同步更新展开图标与数据行显示状态
- 数据行
when条件:绑定isGroupExpanded函数,仅在对应分组展开时渲染数据行
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

