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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:42:11