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

