使用@angular/cdk menu实现嵌套导航菜单:子菜单未自动关闭问题
问题核心在于Angular CDK Menu默认不会自动关闭同一层级其他菜单的子菜单,因为顶层菜单属于独立的菜单实例,未启用互斥逻辑。以下是两种可行的解决方法:
方法一:利用cdkMenuGroup原生互斥机制(推荐)
通过将所有顶层菜单放入同一个cdkMenuGroup容器,并开启exclusive属性,让CDK自动处理菜单的互斥展开:
- 修改
menubar.component.html,给顶层菜单容器添加cdkMenuGroup和[exclusive]="true":
<div cdkMenuGroup [exclusive]="true"> @for (item of items; track item.label) { @if (item.children && item.children.length) { <button cdkMenuTriggerFor="menu-{{item.label}}"> {{ item.label }} </button> <app-menu-item [items]="item.children" [menuId]="'menu-' + item.label" ></app-menu-item> } @else { <button>{{ item.label }}</button> } } </div>
这个方式是CDK Menu官方提供的互斥方案,无需额外逻辑,同一组内的菜单会自动在打开新菜单时关闭其他已展开的子菜单。
方法二:手动控制菜单关闭逻辑
如果需要更灵活的控制,可以通过ViewChildren获取所有顶层菜单的trigger实例,在点击时手动关闭其他菜单:
- 修改
menubar.component.ts,添加菜单trigger的查询和关闭方法:
import { Component, Input, ViewChildren, QueryList } from '@angular/core'; import { CdkMenuTrigger } from '@angular/cdk/menu'; import { NavItem } from './nav-item'; @Component({ selector: 'app-menubar', templateUrl: './menubar.component.html', styleUrls: ['./menubar.component.scss'], }) export class MenubarComponent { @Input() items: NavItem[] = []; @ViewChildren(CdkMenuTrigger) menuTriggers!: QueryList<CdkMenuTrigger>; closeOtherMenus(currentTrigger: CdkMenuTrigger) { this.menuTriggers.forEach(trigger => { if (trigger !== currentTrigger && trigger.menuOpen) { trigger.closeMenu(); } }); } }
- 在
menubar.component.html中给顶层菜单按钮绑定点击事件:
@for (item of items; track item.label) { @if (item.children && item.children.length) { <button cdkMenuTriggerFor="menu-{{item.label}}" (click)="closeOtherMenus($event.target)" > {{ item.label }} </button> <app-menu-item [items]="item.children" [menuId]="'menu-' + item.label" ></app-menu-item> } @else { <button>{{ item.label }}</button> } }
内容的提问来源于stack exchange,提问作者Pain
相关产品推荐
相关产品推荐

