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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:15:38