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

如何在TS文件中编程式展开Mat Table表格中的mat-rows行?

多级嵌套Mat Table通过TS代码控制行展开实现方案

你当前使用的三级可展开Mat Table本质是通过行数据对应的布尔状态字段控制展开/收起状态,通过TS代码控制只需要修改对应行的状态字段再触发表格重渲染即可,具体实现步骤如下:


步骤1:给各层级数据定义展开状态字段

首先确保你的数据源结构中,每个层级的行数据都有对应的独立展开状态标记,示例结构参考:

// 一级行数据结构
export interface Level1Item {
  id: number;
  name: string;
  isExpanded: boolean; // 控制一级行展开状态
  level2Items: Level2Item[];
}
// 二级行数据结构
export interface Level2Item {
  id: number;
  name: string;
  parentId: number;
  isSecondLevelExpanded: boolean; // 控制二级行展开状态
  level3Items: Level3Item[];
}
// 三级行数据结构
export interface Level3Item {
  id: number;
  name: string;
  parentId: number;
  isThirdLevelExpanded: boolean; // 控制三级行展开状态
}

步骤2:封装行展开控制方法

在TS文件中封装按条件匹配目标行、修改展开状态的方法,支持按ID、名称等业务规则定位行:

import { MatTableDataSource } from '@angular/material/table';

// 初始化的一级表格数据源
dataSource = new MatTableDataSource<Level1Item>();

/**
 * 展开指定一级行
 * @param targetId 目标一级行ID
 * @param exclusive 是否排他展开(是则关闭其他同级已展开行,否则保留其他展开状态)
 */
expandLevel1Row(targetId: number, exclusive: boolean = false) {
  this.dataSource.data.forEach(item => {
    if (exclusive) {
      item.isExpanded = item.id === targetId;
    } else if (item.id === targetId) {
      item.isExpanded = true;
    }
  });
  // 触发表格重渲染
  this.dataSource._updateChangeSubscription();
}

/**
 * 展开指定二级行,会自动展开对应的父级一级行
 * @param parentLevel1Id 父级一级行ID
 * @param targetLevel2Id 目标二级行ID
 * @param exclusive 是否排他展开
 */
expandLevel2Row(parentLevel1Id: number, targetLevel2Id: number, exclusive: boolean = false) {
  const parentLevel1 = this.dataSource.data.find(item => item.id === parentLevel1Id);
  if (!parentLevel1) return;
  // 先展开父级一级行
  parentLevel1.isExpanded = true;
  parentLevel1.level2Items.forEach(level2Item => {
    if (exclusive) {
      level2Item.isSecondLevelExpanded = level2Item.id === targetLevel2Id;
    } else if (level2Item.id === targetLevel2Id) {
      level2Item.isSecondLevelExpanded = true;
    }
  });
  this.dataSource._updateChangeSubscription();
}

/**
 * 展开指定三级行,会自动展开对应的一级、二级父级行
 * @param parentLevel1Id 父级一级行ID
 * @param parentLevel2Id 父级二级行ID
 * @param targetLevel3Id 目标三级行ID
 * @param exclusive 是否排他展开
 */
expandLevel3Row(parentLevel1Id: number, parentLevel2Id: number, targetLevel3Id: number, exclusive: boolean = false) {
  const parentLevel1 = this.dataSource.data.find(item => item.id === parentLevel1Id);
  if (!parentLevel1) return;
  parentLevel1.isExpanded = true;
  const parentLevel2 = parentLevel1.level2Items.find(item => item.id === parentLevel2Id);
  if (!parentLevel2) return;
  parentLevel2.isSecondLevelExpanded = true;
  parentLevel2.level3Items.forEach(level3Item => {
    if (exclusive) {
      level3Item.isThirdLevelExpanded = level3Item.id === targetLevel3Id;
    } else if (level3Item.id === targetLevel3Id) {
      level3Item.isThirdLevelExpanded = true;
    }
  });
  this.dataSource._updateChangeSubscription();
}

步骤3:对齐HTML层状态绑定

确保你的HTML模板中,各层级展开的判定条件和TS中修改的状态字段完全对应,示例参考:

<!-- 一级展开内容判定 -->
<div class="level1-expand-content" *ngIf="element.isExpanded">
  <!-- 二级表格内容 -->
  <div class="level2-expand-content" *ngIf="subElement.isSecondLevelExpanded">
    <!-- 三级表格内容 -->
    <div class="level3-expand-content" *ngIf="thirdElement.isThirdLevelExpanded">
      三级展开内容
    </div>
  </div>
</div>

常见注意事项

  • 如果你的表格是展开时才动态加载子级数据,需要先触发子级数据加载逻辑,再修改对应行的展开状态
  • 如果你的数据源使用BehaviorSubject维护,替换_updateChangeSubscription()调用为next方法更新数据源即可生效
  • 收起行的逻辑和展开逻辑一致,只需要把对应状态字段设为false即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:18:01