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

Angular Material Mat Tree Toggle手风琴式展开折叠实现求助

实现Angular Material Mat Tree手风琴式展开/折叠效果

要实现点击新节点展开时自动收起其他已展开节点的手风琴效果,需要自定义节点切换逻辑,替代默认的matTreeNodeToggle指令,具体操作如下:

1. 修改模板代码

移除按钮上的matTreeNodeToggle指令,绑定自定义的点击事件,保持原有图标逻辑不变:

<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
    <!-- 叶子节点模板 -->
    <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding
        [style.background]="treeControl.isExpanded(node) ? '#DEEAFF' : ''">
        <mat-list-item routerLink="{{node.path}}">{{node.name}}</mat-list-item>
    </mat-tree-node>

    <!-- 可展开节点模板 -->
    <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding
        [style.background]="treeControl.isExpanded(node) ? '#DEEAFF' : ''">
        <mat-list-item>
            <!-- 替换默认指令为自定义点击事件 -->
            <button mat-icon-button disableRipple [attr.aria-label]="'toggle ' + node.name"
                (click)="toggleNode(node)">
                {{node.name}}
            </button>
        </mat-list-item>
        <mat-icon class="mat-icon-rtl-mirror" color="primary">
            {{treeControl.isExpanded(node) ? 'expand_less' : 'expand_more'}}
        </mat-icon>
    </mat-tree-node>
</mat-tree>

2. 组件类中添加自定义切换逻辑

在组件类里实现toggleNode方法,处理关闭其他节点、切换当前节点状态的逻辑:

import { Component } from '@angular/core';
import { MatTreeControl } from '@angular/material/tree';

// 替换成你项目中实际的节点类型定义
interface TreeNode {
  name: string;
  path?: string;
  children?: TreeNode[];
}

@Component({
  // 保留你原有的组件元数据配置
})
export class YourTreeComponent {
  treeControl = new MatTreeControl<TreeNode>(node => node.children?.length || 0);
  dataSource: any; // 替换成你实际的数据源类型

  // 判断节点是否有子节点的方法(保留你原有的逻辑)
  hasChild = (_: number, node: TreeNode) => !!node.children && node.children.length > 0;

  constructor() {
    // 保留你原有的数据源初始化逻辑
    // this.dataSource = ...
  }

  // 自定义节点切换方法
  toggleNode(node: TreeNode) {
    // 如果当前节点已展开,直接关闭
    if (this.treeControl.isExpanded(node)) {
      this.treeControl.collapse(node);
      return;
    }

    // 关闭所有已展开的节点
    this.treeControl.expandedNodes.forEach(expandedNode => {
      this.treeControl.collapse(expandedNode);
    });

    // 展开当前节点
    this.treeControl.expand(node);
  }
}

说明

  • 逻辑核心:点击节点时先判断状态——若已展开则直接关闭;若未展开,先关闭所有已打开的节点,再展开当前节点。
  • 请替换代码中的YourTreeComponent和TreeNode为你项目中实际的组件类名与节点类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:31:12