如何以编程方式打开mat-menu?

Roe*_*oel 13 typescript angular-material2 angular

我在点击mat-nav-list项目时尝试触发打开菜单.

HTML

<mat-nav-list>
    <mat-list-item (click)="onOpenMenu(menu)" *ngFor="let i of data">
        <div mat-line>
            {{ i.name }}
        </div>
        <p mat-line>
            {{ i.email }}
        </p>
        <button mat-icon-button [matMenuTriggerFor]="menu">
            <mat-icon>more_vert</mat-icon>
        </button>
    </mat-list-item>
    <mat-menu #menu="matMenu">
        <button mat-menu-item>View profile</button>
        <button mat-menu-item>Add contact</button>
    </mat-menu>
</mat-nav-list>
Run Code Online (Sandbox Code Playgroud)

TS

onOpenMenu(menu: any): void {
   // menu doesn't have any openMenu() function 
   // which is of course not a trigger object but a menu itself.
   console.log(menu);
}
Run Code Online (Sandbox Code Playgroud)

我一直试图在github上看这个问题,这更接近我的情况.但在我的情况下,我有一个动态的项目列表,我想每次点击打开一个菜单.

DEMO

yur*_*zui 30

你需要MatMenuTrigger[matMenuTriggerFor]元素中获取实例

#menuTrigger="matMenuTrigger"  [matMenuTriggerFor]="menu"
Run Code Online (Sandbox Code Playgroud)

哪里

  • #menuTrigger 是模板引用变量

  • matMenuTrigger是元数据的exportAs属性MatMenuTrigger

然后简单地打电话

(click)="menuTrigger.openMenu()"
Run Code Online (Sandbox Code Playgroud)

Stackblitz的例子

在这里阅读更多关于模板参考变量


小智 11

也可以<mat-menu>直接在代码中控制。下面是一个例子:

import { Component, ViewChild } from '@angular/core';
import { MatMenuTrigger } from '@angular/material/menu';

...
export class LanguageComponent {
  @ViewChild('languageMenuTrigger') languageMenuTrigger: MatMenuTrigger;
  
  ...

  openMenu() {
    this.languageMenuTrigger.openMenu();
  }
  
  closeMenu() {
    this.languageMenuTrigger.closeMenu();
  }
}
Run Code Online (Sandbox Code Playgroud)
<button
  mat-button
  [matMenuTriggerFor]="languageMenu"
  #languageMenuTrigger="matMenuTrigger">
  Language
  <mat-icon>expand_more</mat-icon>
</button>
<mat-menu #languageMenu="matMenu">
  <button
    mat-menu-item>
    English
  </button>
  <button
    mat-menu-item>
    Français
  </button>
</mat-menu>
Run Code Online (Sandbox Code Playgroud)


Dom*_*erg 8

如果您想以编程方式完全控制它,而网站上没有一个也控制菜单的元素,您可以声明一个包含 的元素[matMenuTriggerFor],但通过 CSS 隐藏它。

注意:您必须手动定位菜单。你可以大致这样做:

模板:

<div #menuTrigger [matMenuTriggerFor]="menu" class="menu-trigger">I will be hidden</div>
<mat-menu #menu class="your-menu-class">
...
</mat-menu>
Run Code Online (Sandbox Code Playgroud)

CSS:

.menu-trigger {
  display: none;
}
Run Code Online (Sandbox Code Playgroud)

成分:

class YourComponent {
  @ViewChild(MatMenuTrigger) menuTrigger: MatMenuTrigger | undefined;

  constructor(private readonly viewRef: ViewContainerRef) { }

  someMethod() {
    this.menuTrigger?.menuOpened.pipe(take(1)).subscribe(() => {
      const menu = document.getElementsByClassName('your-menu-class')[0] as HTMLElement;
      const position: DOMRect = this.viewRef.element.nativeElement.getBoundingClientRect();

      menu.style.position = 'absolute';
      menu.style.top = `${position.top}px`;
      menu.style.left = `${position.width}px`;
    });

    this.menuTrigger?.openMenu();
  }
}
Run Code Online (Sandbox Code Playgroud)