多ng-template嵌套的Mat-Menu子菜单自动关闭问题求助
当把Mat-Menu的子菜单嵌套在ng-template内部时,Angular Material的菜单触发器([matMenuTriggerFor])和对应的子菜单组件不在同一个视图上下文里,导致菜单的交互逻辑(比如鼠标悬停/点击的事件追踪)出现异常,触发菜单自动关闭的逻辑。
方案一:调整模板结构,保持触发器与子菜单的作用域关联
将子菜单定义在主组件的作用域中,而非嵌套在ng-template内部,通过模板上下文传递菜单引用给复用的模板。
修改后的代码示例:
<button mat-button [matMenuTriggerFor]="menu3"> Submenu in cascading containers and templates </button> <mat-menu #menu3="matMenu"> <ng-container *ngTemplateOutlet="mainMenu3; context: { subMenu: subMenu3 }"></ng-container> </mat-menu> <!-- 子菜单定义在组件作用域,而非模板内部 --> <mat-menu #subMenu3> <ng-container *ngTemplateOutlet="subSubNenu3"></ng-container> </mat-menu> <ng-template #mainMenu3 let-subMenu="subMenu"> <button mat-menu-item [matMenuTriggerFor]="subMenu"> Submenu in a template </button> </ng-template> <ng-template #subSubNenu3> <button mat-menu-item>Submenu Item</button> </ng-template>
说明:
- 将
subMenu3从mainMenu3模板中移出,放在组件的根作用域下,确保触发器[matMenuTriggerFor]能直接关联到菜单实例。 - 通过
*ngTemplateOutlet的context参数,把subMenu3的引用传递给mainMenu3模板,实现模板复用的同时保持菜单关联关系。
方案二:用组件封装菜单(更适合复杂复用场景)
如果需要更复杂的菜单复用,建议把每个菜单部分封装成独立组件,组件内部的触发器和菜单自然处于同一视图上下文,不会出现关联问题。
示例组件结构:
- 创建
main-menu.component.html:
<button mat-menu-item [matMenuTriggerFor]="subMenu"> Submenu in a template </button> <mat-menu #subMenu> <app-sub-sub-menu></app-sub-sub-menu> </mat-menu>
- 创建
sub-sub-menu.component.html:
<button mat-menu-item>Submenu Item</button>
- 父组件中使用:
<button mat-button [matMenuTriggerFor]="menu3"> Submenu in cascading containers and templates </button> <mat-menu #menu3="matMenu"> <app-main-menu></app-main-menu> </mat-menu>
说明:
- 组件封装后,每个菜单的触发器和子菜单都在组件内部的视图容器中,Angular Material能正确处理菜单的层级交互,同时实现了更高程度的复用性。
内容的提问来源于stack exchange,提问作者ErickXavier
相关产品推荐
相关产品推荐

