Angular中MatMenu无可用MatMenuItem时如何禁用触发MatButton
更简便的实现方案
你不需要手动枚举所有菜单项的显示条件,直接借助MatMenu实例暴露的items属性就能自动统计当前可见的菜单项数量,从根源上避免多条件维护的问题。
最简实现(仅判断菜单项是否可见)
MatMenu内部通过@ContentChildren(MatMenuItem)查询所有已渲染的菜单项,被*ngIf隐藏的菜单项不会进入DOM,自然不会出现在items列表中,你可以直接在模板里绑定判断逻辑:
<!-- 注意原示例中的[disable]是拼写错误,正确的禁用属性是[disabled] --> <button mat-button [matMenuTriggerFor]="menu" [disabled]="!menu.items?.length"> Menu </button> <mat-menu #menu="matMenu"> <button mat-menu-item *ngIf="condition1">Item 1</button> <button mat-menu-item *ngIf="condition2">Item 2</button> <button mat-menu-item *ngIf="condition3">Item 3</button> <!-- 其余菜单项不需要额外调整 --> <button mat-menu-item *ngIf="conditionN">Item N</button> </mat-menu>
这种写法不需要写任何额外的TS逻辑,新增、删除菜单项时不需要修改触发器的禁用判断,不会出现漏写条件的问题。
进阶实现(排除显示但禁用的菜单项)
如果你有部分菜单项是可见但被禁用的状态,需要判断是否存在可点击的菜单项时,只需要在组件类中加一个计算属性即可:
- 先在组件中引入
MatMenu,通过ViewChild拿到菜单实例
import { Component, ViewChild } from '@angular/core'; import { MatMenu } from '@angular/material/menu'; @Component({ selector: 'your-component', templateUrl: './your-component.html' }) export class YourComponent { @ViewChild('menu') menu!: MatMenu; // 计算是否存在可用菜单项 get hasEnabledItem(): boolean { return this.menu?.items?.some(item => !item.disabled) ?? false; } }
- 调整模板中触发器的禁用绑定
<button mat-button [matMenuTriggerFor]="menu" [disabled]="!hasEnabledItem"> Menu </button>
注意事项
items是Angular Material维护的QueryList类型数据,当菜单项的显示/禁用状态变化时会自动同步,绑定的判断逻辑会自动更新,不需要手动触发变更检测- 不要继续使用手动枚举所有条件的写法,菜单项数量多了之后维护成本极高,很容易出现空菜单、按钮错误禁用/启用的问题
内容的提问来源于stack exchange,提问作者ar099968
相关产品推荐
相关产品推荐

