Angular 19中NestedTreeControl已弃用,求替代方案及展开功能示例
Angular 19 + Material v3 树形组件节点展开示例(替代弃用的NestedTreeControl)
在Angular Material v3中,NestedTreeControl已被弃用,取而代之的是直接使用TreeControl,通过配置层级获取器(levelAccessor)和子节点判断器来实现树形节点的管理,包括展开/折叠等核心功能,原有的expand()、collapse()等方法依然保留可用。
以下是完整的可运行示例:
组件代码(tree-demo.component.ts)
import { Component } from '@angular/core'; import { MatTreeModule, TreeControl } from '@angular/material/tree'; import { MatButtonModule } from '@angular/material/button'; import { CommonModule } from '@angular/common'; // 自定义树形节点数据结构,根据你的业务需求调整 interface TreeNode { name: string; children?: TreeNode[]; parent?: TreeNode; // 可选,用于层级计算,若没有可通过其他方式实现 } // 模拟树形数据 const TREE_DATA: TreeNode[] = [ { name: '项目总览', children: [ { name: '用户管理', parent: null }, { name: '内容管理', parent: null, children: [{ name: '文章列表', parent: null }, { name: '分类管理', parent: null }] } ] }, { name: '系统设置', children: [{ name: '权限配置', parent: null }, { name: '日志查看', parent: null }] } ]; // 初始化时给子节点设置parent引用(用于层级计算) const setParentReferences = (nodes: TreeNode[], parent: TreeNode | null) => { nodes.forEach(node => { node.parent = parent; if (node.children) { setParentReferences(node.children, node); } }); }; setParentReferences(TREE_DATA, null); @Component({ selector: 'app-tree-demo', standalone: true, imports: [CommonModule, MatTreeModule, MatButtonModule], templateUrl: './tree-demo.component.html' }) export class TreeDemoComponent { // 初始化TreeControl,传入层级获取器和子节点判断器 treeControl = new TreeControl<TreeNode>( node => this.getNodeLevel(node), node => this.hasChildNodes(node) ); treeDataSource = TREE_DATA; // 计算节点层级(根节点为0,子节点层级+1) getNodeLevel(node: TreeNode): number { let level = 0; let currentNode = node; while (currentNode.parent) { level++; currentNode = currentNode.parent; } return level; } // 判断节点是否存在子节点 hasChildNodes(node: TreeNode): boolean { return !!node.children && node.children.length > 0; } // 手动展开指定节点 expandTargetNode(node: TreeNode): void { this.treeControl.expand(node); } // 手动折叠指定节点 collapseTargetNode(node: TreeNode): void { this.treeControl.collapse(node); } // 展开所有节点 expandAllNodes(): void { this.treeControl.expandAll(); } // 折叠所有节点 collapseAllNodes(): void { this.treeControl.collapseAll(); } }
模板代码(tree-demo.component.html)
<!-- 树形结构主体 --> <mat-tree [dataSource]="treeDataSource" [treeControl]="treeControl"> <!-- 普通节点模板(无子女节点) --> <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle> <li class="mat-tree-node"> <button mat-icon-button disabled></button> {{ node.name }} </li> </mat-tree-node> <!-- 带子女节点的模板 --> <mat-nested-tree-node *matTreeNodeDef="let node; when: hasChildNodes"> <li> <div class="mat-tree-node"> <!-- 内置展开/折叠切换按钮 --> <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'切换 ' + node.name" > <mat-icon class="mat-icon-rtl-mirror"> {{ treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right' }} </mat-icon> </button> {{ node.name }} <!-- 自定义手动展开/折叠按钮 --> <button mat-button (click)="expandTargetNode(node)">展开</button> <button mat-button (click)="collapseTargetNode(node)">折叠</button> </div> <!-- 子节点容器,根据展开状态控制显示 --> <ul [class.mat-tree-invisible]="!treeControl.isExpanded(node)"> <ng-container matTreeNodeOutlet></ng-container> </ul> </li> </mat-nested-tree-node> </mat-tree> <!-- 全局操作按钮组 --> <div style="margin-top: 16px; padding-left: 16px;"> <button mat-button (click)="expandAllNodes()">展开全部</button> <button mat-button (click)="collapseAllNodes()">折叠全部</button> </div>
关键说明
- 不再依赖
NestedTreeControl,直接使用TreeControl并传入两个核心函数:- 第一个参数是levelAccessor:用于计算节点的层级,控制树形结构的缩进
- 第二个参数是子节点判断函数:用于标识节点是否包含子节点,决定是否显示展开/折叠按钮
- 原有
expand()、collapse()、expandAll()、collapseAll()等方法完全保留,用法和之前一致 - 模板中通过
mat-nested-tree-node处理带子女的节点,matTreeNodeToggle指令可实现点击图标自动切换展开/折叠状态,也可通过自定义按钮调用组件内的方法手动控制
内容的提问来源于stack exchange,提问作者Mahyar Pasarzangene
相关产品推荐
相关产品推荐

