Angular动态绑定[matMenuTriggerFor]报createEmbeddedView未定义错误如何解决
问题原因
matMenuTriggerFor指令接收的参数是MatMenu组件的实例对象,而非菜单的模板引用名称字符串。你当前代码中getMenuName方法返回的是字符串'navmenu',和指令要求的入参类型不匹配,点击时框架找不到对应的菜单实例,才会抛出Cannot read property 'createEmbeddedView' of undefined错误。
解决方案
场景1:菜单数量少,可预先获取所有菜单实例
首先在组件类中通过@ViewChild装饰器获取模板中声明的MatMenu实例,在getMenuName方法中直接返回对应实例即可:
import { Component, ViewChild } from '@angular/core'; import { MatMenu } from '@angular/material/menu'; @Component({ // 你的组件配置 }) export class YourComponent { // 绑定模板中的#navmenu引用 @ViewChild('navmenu') navMenu!: MatMenu; // 如有其他菜单,可新增对应的@ViewChild声明 // @ViewChild('userMenu') userMenu!: MatMenu; getMenuName(menuItem: any) { console.log(menuItem); // 根据业务逻辑返回对应菜单实例即可 return this.navMenu; // 示例:根据menuItem的属性切换菜单 // return menuItem.type === 'nav' ? this.navMenu : this.userMenu; } }
模板部分无需修改,沿用你当前的绑定写法即可。
场景2:菜单数量多,不想逐个声明@ViewChild
可以通过@ViewChildren批量获取所有MatMenu实例,预先构建菜单名称到实例的映射表,调用时直接从映射表取对应实例:
import { Component, ViewChildren, QueryList } from '@angular/core'; import { MatMenu } from '@angular/material/menu'; @Component({ // 你的组件配置 }) export class YourComponent { private menuMap: Record<string, MatMenu> = {}; // 批量获取所有MatMenu实例,构建映射表 @ViewChildren(MatMenu) set allMenus(menus: QueryList<MatMenu>) { menus.forEach(menu => { // 这里可以用menu的id、或者你自定义的name属性作为映射key this.menuMap[menu.id] = menu; }) } getMenuName(menuItem: any) { console.log(menuItem); // 传入菜单名称即可拿到对应实例返回 return this.menuMap['navmenu']; } }
极简方案:逻辑简单时直接在模板内判断
如果动态切换的逻辑非常简单,无需封装ts方法,可以直接在模板中用三元表达式绑定:
<button mat-icon-button [matMenuTriggerFor]="menuItem.type === 'nav' ? navmenu : otherMenu"> <mat-icon>{{ menuItem.icon }}</mat-icon> </button>
内容的提问来源于stack exchange,提问作者raju
相关产品推荐
相关产品推荐

