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
相关产品推荐
相关产品推荐

