Angular 14中如何在Mat菜单Apply按钮点击时取消stopPropagation
问题说明
基于最新版Angular开发,使用mat-menu承载包含多选框和Apply按钮的自定义组件。为避免点击菜单区域时弹窗直接关闭,在自定义组件上添加了$event.stopPropagation()阻止事件冒泡,但导致点击Apply按钮时无法触发菜单关闭,需解决该矛盾。
当前代码现状
app.component.html
<button mat-button [matMenuTriggerFor]="menu">Menu</button> <mat-menu #menu="matMenu"> <menu-toolbar (click)="$event.stopPropagation()"></menu-toolbar> </mat-menu>
menu-toolbar.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'menu-toolbar', templateUrl: './menu-toolbar.component.html', styleUrls: ['./menu-toolbar.component.css'] }) export class MenuToolbarComponent { name = 'Angular'; applyChanges(): void { // 执行业务逻辑 console.log('Changes applied successfully...'); } }
menu-toolbar.component.html
<div> <mat-checkbox>Item #1</mat-checkbox> <mat-checkbox>Item #2</mat-checkbox> <mat-checkbox>Item #3</mat-checkbox> </div> <button mat-button (click)="applyChanges($event)">Apply</button>
解决方案
方案1:精准控制事件冒泡(简单直接)
修改父组件中自定义组件的点击事件判断逻辑,仅在点击非按钮元素时阻止事件冒泡,允许按钮的点击事件正常传递到mat-menu触发关闭:
修改app.component.html:
<button mat-button [matMenuTriggerFor]="menu">Menu</button> <mat-menu #menu="matMenu"> <!-- 仅当点击目标不是按钮时才阻止冒泡 --> <menu-toolbar (click)="$event.target.tagName !== 'BUTTON' && $event.stopPropagation()"></menu-toolbar> </mat-menu>
此方法无需修改组件内部逻辑,仅通过事件源判断即可解决问题。
方案2:手动调用菜单关闭API(更灵活)
通过Angular Material提供的MatMenu实例手动控制菜单关闭,适用于需要在Apply按钮执行复杂逻辑后再关闭的场景:
- 修改app.component.ts,获取菜单实例并添加关闭方法:
import { Component, ViewChild } from '@angular/core'; import { MatMenu } from '@angular/material/menu'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { @ViewChild('menu') menu!: MatMenu; closeMenu(): void { this.menu.close(); } }
- 修改app.component.html,给自定义组件绑定关闭菜单的输出事件:
<button mat-button [matMenuTriggerFor]="menu">Menu</button> <mat-menu #menu="matMenu"> <menu-toolbar (click)="$event.stopPropagation()" (apply)="closeMenu()"></menu-toolbar> </mat-menu>
- 修改menu-toolbar.component.ts,添加输出事件并在Apply时触发:
import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'menu-toolbar', templateUrl: './menu-toolbar.component.html', styleUrls: ['./menu-toolbar.component.css'] }) export class MenuToolbarComponent { name = 'Angular'; @Output() apply = new EventEmitter<void>(); applyChanges(): void { // 执行业务逻辑 console.log('Changes applied successfully...'); // 触发关闭菜单事件 this.apply.emit(); } }
两种方案均可解决问题,方案1适合简单场景,方案2更适合需要自定义关闭时机的复杂业务逻辑。
内容的提问来源于stack exchange,提问作者Govindamma
相关产品推荐
相关产品推荐

