You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:54:04