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

Angular Material嵌套节点树形表格:如何手动实现节点切换?

如何在嵌套树形Material Table中手动实现节点切换

核心思路

嵌套树形表格的节点切换本质是通过维护节点的展开状态,并根据状态动态控制子节点的显示/隐藏,同时更新表格的渲染逻辑。以下是具体实现步骤:


1. 给嵌套节点添加展开状态字段

首先在你的节点数据结构中新增一个expanded布尔属性,用来标记当前节点的展开状态:

interface NestedNode {
  name: string;
  // 其他业务字段
  children?: NestedNode[];
  expanded: boolean; // 新增:标记节点是否展开
}

初始化数据时,默认将所有节点设为expanded: false(折叠状态)。

2. 实现节点切换的核心方法

在组件中编写切换节点状态的方法,点击节点时触发状态反转:

toggleNode(node: NestedNode): void {
  node.expanded = !node.expanded;
  // 可选:如果需要联动子节点(比如展开父节点时自动展开所有子节点),可以在此添加递归逻辑
}

3. 在模板中绑定交互与状态

在表格的列定义模板里,给可展开的节点添加点击事件,并根据expanded状态显示对应图标:

<ng-container matColumnDef="name">
  <th mat-header-cell *matHeaderCellDef> 节点名称 </th>
  <td mat-cell *matCellDef="let element">
    <!-- 仅当节点有子节点时显示切换按钮 -->
    <button mat-icon-button (click)="toggleNode(element)" *ngIf="element.children?.length">
      <mat-icon>{{ element.expanded ? 'expand_more' : 'chevron_right' }}</mat-icon>
    </button>
    {{ element.name }}
  </td>
</ng-container>

4. 动态渲染子节点

根据节点的expanded状态,决定是否渲染其子节点。如果是通过递归方式渲染表格行,可以用*ngIf结合嵌套循环实现:

<!-- 渲染父节点行 -->
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

<!-- 递归渲染展开的子节点 -->
<ng-container *ngIf="row.expanded && row.children">
  <tr mat-row *ngFor="let child of row.children" [style.padding-left.px]="20">
    <td mat-cell *matCellDef="let col" [attr.colspan]="displayedColumns.length">
      <!-- 复用父节点的单元格结构,或者调用递归组件渲染子节点 -->
      <button mat-icon-button (click)="toggleNode(child)" *ngIf="child.children?.length">
        <mat-icon>{{ child.expanded ? 'expand_more' : 'chevron_right' }}</mat-icon>
      </button>
      {{ child.name }}
    </td>
  </tr>
</ng-container>

5. 可选:扁平化数据适配表格渲染

如果你的Material Table依赖扁平化数组来渲染,可以在组件中维护一个displayedData数组,当节点切换时动态更新这个数组:

displayedData: NestedNode[] = [];
rootNodes: NestedNode[] = []; // 你的原始嵌套节点数据

ngOnInit(): void {
  this.updateDisplayedData(this.rootNodes);
}

// 递归生成扁平化的显示数组
updateDisplayedData(nodes: NestedNode[], depth = 0): void {
  nodes.forEach(node => {
    this.displayedData.push({ ...node, depth });
    if (node.expanded && node.children) {
      this.updateDisplayedData(node.children, depth + 1);
    }
  });
}

toggleNode(node: NestedNode): void {
  node.expanded = !node.expanded;
  this.displayedData = [];
  this.updateDisplayedData(this.rootNodes);
}

然后在模板中直接绑定displayedData作为表格数据源即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 01:33:24