简体   繁体   English

Angular 5 Material Multiple mat-menu

[英]Angular 5 Material Multiple mat-menu

I am quite new to Angular 5 and have just started learning it.我对 Angular 5 很陌生,刚刚开始学习它。

Recently, I have been trying to create a menu bar with multiple menus for my app using Angular 5 Material.最近,我一直在尝试使用 Angular 5 Material 为我的应用程序创建一个带有多个菜单的菜单栏。
The menu will be triggered/opened during mouse enter and closed when the mouse leaves the menu.鼠标进入时会触发/打开菜单,鼠标离开菜单时会关闭菜单。
My problem is that everytime the mouse mouse hovers to the first menu it loads the menu items of the 2nd menu.我的问题是,每次鼠标悬停到第一个菜单时,它都会加载第二个菜单的菜单项。

Here is a screenshot of the problem:这是问题的屏幕截图:
在此处输入图片说明

Here are my codes:这是我的代码:
mainmenu.component.html : mainmenu.component.html :

<div>
    <button mat-button [matMenuTriggerFor]="menu1" 
      (mouseenter)="openMyMenu()">Trigger1</button>
    <mat-menu #menu1="matMenu" overlapTrigger="false">
        <span (mouseleave)="closeMyMenu()">
            <button mat-menu-item>Item 1</button>
            <button mat-menu-item>Item 2</button>
        </span>
   </mat-menu>
</div>
<div>
    <button mat-button [matMenuTriggerFor]="menu2"
      (mouseenter)="openMyMenu()">Trigger2</button>
    <mat-menu #menu2="matMenu" overlapTrigger="false">
        <span (mouseleave)="closeMyMenu()">
            <button mat-menu-item>Item 3</button>
            <button mat-menu-item>Item 4</button>
        </span>
    </mat-menu>
</div>



mainmenu.component.ts : mainmenu.component.ts :

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

@Component({
  selector: 'app-mainmenu',
  templateUrl: './mainmenu.component.html',
  styleUrls: ['./mainmenu.component.css']
})
export class MainmenuComponent implements OnInit {
  @ViewChild(MatMenuTrigger) matMenuTrigger: MatMenuTrigger;

  constructor() { }

  ngOnInit() {
  }
  openMyMenu() {
    this.matMenuTrigger.openMenu();

  } 
  closeMyMenu() {
    this.matMenuTrigger.closeMenu();
  }
}

I also tried this: @ViewChild('menu1') matMenuTrigger: MatMenuTrigger;我也试过这个: @ViewChild('menu1') matMenuTrigger: MatMenuTrigger; but I am getting errors.但我收到错误。
Your opinions and advices are very much appreciated!非常感谢您的意见和建议!


Thanks,谢谢,
Artanis Zeratul阿塔尼斯·泽拉图

References:参考:


The correct solution for this problem:此问题的正确解决方案:

@ViewChildren(MatMenuTrigger) trigger: QueryList<MatMenuTrigger>;

//And call:

me.trigger.toArray()[indexOfMenu].openMenu();

I had the same issue.我遇到过同样的问题。

Create two separate components, each will then contain its own mat-menu and will not affect the other.创建两个单独的组件,然后每个组件都将包含自己的 mat-menu 并且不会影响另一个。

<!-- component1 -->
<div>
 <button mat-button [matMenuTriggerFor]="menu1" 
  (mouseenter)="openMyMenu()">Trigger1</button>
 <mat-menu #menu1="matMenu" overlapTrigger="false">
    <span (mouseleave)="closeMyMenu()">
        <button mat-menu-item>Item 1</button>
        <button mat-menu-item>Item 2</button>
    </span>
</mat-menu>
</div>

<!-- component2 -->
<div>
<button mat-button [matMenuTriggerFor]="menu2"
  (mouseenter)="openMyMenu()">Trigger2</button>
<mat-menu #menu2="matMenu" overlapTrigger="false">
    <span (mouseleave)="closeMyMenu()">
        <button mat-menu-item>Item 3</button>
        <button mat-menu-item>Item 4</button>
    </span>
 </mat-menu>
</div>

I have two matmenus in my toolbar each one is a separate component and triggers a separate matmenu.我的工具栏中有两个 matmenus,每个都是一个单独的组件并触发一个单独的 matmenu。

See images below:见下图:

在此处输入图片说明

Here is my notifications component(component 1 in the image above) In my editor view :这是我的通知组件(上图中的组件 1)在我的编辑器视图中:

在此处输入图片说明

In my notifications.component.html file :在我的notifications.component.html 文件中:

<button mat-icon-button [matMenuTriggerFor]="notificationsMenu" (mouseover)="openNotifications()">
  <mat-icon class="material-icons ele-text-color-grey">notifications</mat-icon>
</button>

<mat-menu #notificationsMenu="matMenu" [overlapTrigger]="false"></mat-menu>

I don't think it is possible to have two in one component but I hope this helps.我认为不可能将两个组件合二为一,但我希望这会有所帮助。

This issue is related to the element referencing in angular, so you cannot directly use the multiple mat-menu in a single component.此问题与 angular 中的元素引用有关,因此您不能在单个组件中直接使用多个 mat-menu。

The trick to do is to create a separate component that implements the mat-menu: Eg,诀窍是创建一个单独的组件来实现 mat-menu:例如,

mat-menu.component.html: mat-menu.component.html:

`<div>
    <span>
        <a (click)="openSelectMenu()">Menu
        <mat-icon>arrow_drop_down</mat-icon>
        <div #menuTrigger="matMenuTrigger" [matMenuTriggerFor]="menu1"></div>
        </a>
        <mat-menu #menu1="matMenu" overlapTrigger="false">
        <a mat-menu-item *ngFor="let menu of menuItems">{{menu}}</a></mat-menu>
    </span>
</div>`

mat-menu.component.ts mat-menu.component.ts

`@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;`
`menuItems=['1', '2', '3'];`

 `openSelectMenu() {
    this.trigger.openMenu();
 }`

Now you can use this component multiple times in any component.现在您可以在任何组件中多次使用该组件。 Eg, app.component.html例如,app.component.html

`<app-menu></app-menu>
<app-menu></app-menu>`

It will work.它会起作用。

<ul class="navbar-nav ml-auto">
  <li class="nav-item dropdown">
      <button mat-button [matMenuTriggerFor]="admin">ADMIN</button>
      <mat-menu #admin="matMenu">
        <button mat-menu-item>User Management</button>
      </mat-menu>
  </li>
  <li class="nav-item dropdown">
      <button mat-button [matMenuTriggerFor]="profile">PROFILE</button>
      <mat-menu #profile="matMenu">
        <button mat-menu-item>Change Password</button>
        <button mat-menu-item>Logout</button>
      </mat-menu>
  </li>

I had the same issue and I solved it by using the read metadata property of @ViewChild decorator我遇到了同样的问题,我通过使用 @ViewChild 装饰器的read元数据属性解决了它

mainmenu.component.html主菜单.component.html

<button #menuBtn1 [matMenuTriggerFor]="menu1">Trigger1</button>
<button #menuBtn2 [matMenuTriggerFor]="menu2">Trigger2</button>

mainmenu.component.ts主菜单.component.ts

@ViewChild('menuBtn1', { read: MatMenuTrigger, static: false}) menu1: MatMenuTrigger;
@ViewChild('menuBtn2', { read: MatMenuTrigger, static: false}) menu2: MatMenuTrigger;

foo() {
    this.menu1.openMenu(); // also closeMenu()
    this.menu2.openMenu();
}

The trick is to use the template reference menuBtn1 or menuBtn2 and specify through the read property what you want to get that is the MatMenuTrigger directive诀窍是使用模板引用menuBtn1menuBtn2并通过read属性指定您想要获取的内容,即MatMenuTrigger指令

NOTE: I saw that the question refers to angular and angular-material 5. I tested it with angular 8 but it should be the same注意:我看到这个问题是指 angular 和 angular-material 5。我用 angular 8 测试过,但应该是一样的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM