Угловой 5 Материал Множественный мат-меню

Я новичок в Angular 5 и только начал его изучать.

Недавно я пытался создать строку меню с несколькими меню для своего приложения, используя материал Angular 5.
Меню будет запускаться / открываться при вводе мыши и закрываться, когда мышь покидает меню.
Моя проблема в том, что каждый раз, когда мышь наводит курсор на первое меню, она загружает пункты меню второго меню.

Вот скриншот проблемы:
введите описание изображения здесь

Вот мои коды:
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:

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();
  }
}

Я тоже пробовал это: @ViewChild('menu1') matMenuTrigger: MatMenuTrigger;, но получаю ошибки.
Мы очень ценим ваше мнение и советы!


Спасибо,
Артанис Зератул

Ссылки:



person Artanis Zeratul    schedule 12.07.2018    source источник


Ответы (6)


Я была такая же проблема.

Создайте два отдельных компонента, каждый из которых будет содержать свое собственное меню-мат и не повлияет на другой.

<!-- 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>
person nontechguy    schedule 15.07.2018
comment
@ArtanisZeratul, если это помогло решить вашу проблему, пожалуйста, сделайте одолжение и щелкните стрелку, чтобы отметить ее как полезную, спасибо. - person nontechguy; 18.07.2018
comment
Что, если я хочу использовать 2 matmenu в одном компоненте? - person Maulik; 20.11.2018
comment
@Maulik, вы имеете в виду вложенное матменю - material.angular.io/components/menu/overview - person nontechguy; 29.11.2018
comment
Нет. Я хочу применить два контекстных меню в одном компоненте. Но срабатывает только первый, а не второй. Сценарий таков: при щелчке правой кнопкой мыши по строке таблицы я хочу открыть matmenu, и у меня есть другая таблица, на которой щелкните правой кнопкой мыши, я хочу открыть второе matmenu. Но когда я щелкаю правой кнопкой мыши по любому из них, запускается только первое matMenu. - person Maulik; 30.11.2018
comment
@Maulik, тогда мое исходное решение должно работать. Создайте два отдельных компонента. У меня есть два matmenu на моей верхней панели инструментов, и каждое из них представляет собой отдельный компонент, который включает в себя matmenu и кнопку. - person nontechguy; 30.11.2018
comment
Но, братан, в моем приложении около 10 меню. Итак, я должен создать для него 10 различных компонентов? Как передавать данные от одного к другому, это также требование для передачи данных при щелчке по каждому пункту меню? - person Maulik; 30.11.2018
comment
Будет полезно, если вы предоставите свой код, чтобы я мог наблюдать, как вы его достигли. - person Maulik; 30.11.2018
comment
@Maulik У меня такая же проблема. Ответ Ласло Лебера сработал идеально. Просто убедитесь, что вы импортируете ViewChildren и QueryList из @ angular / core. - person Naser AlOqab; 12.09.2019

Правильное решение этой проблемы:

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

//And call:

me.trigger.toArray()[indexOfMenu].openMenu();
person László Leber    schedule 05.02.2019
comment
Это должно быть отмечено как правильный ответ. Спасибо! - person Naser AlOqab; 12.09.2019
comment
Это то, что я ищу. но вроде не работает. триггер имеет тип MatMenuTrigger, а не список запросов этого типа. Ты знаешь почему? - person SHMT; 04.03.2020
comment
Это сработало отлично! Поскольку триггеры генерируются оператором * ngFor вместе с целью меню, я предоставил индекс функции меню, как указано в ответе, что позволило ей выбрать соответствующий триггер из массива. - person Michael Barrett; 30.06.2020

У меня есть два matmenus на моей панели инструментов, каждое из которых является отдельным компонентом и запускает отдельное matmenu.

См. изображения ниже:

введите описание изображения здесь

Вот мой компонент уведомлений (компонент 1 на изображении выше) В моем редакторе:

введите описание изображения здесь

В моем файле 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>

Я не думаю, что возможно объединить два компонента в одном, но надеюсь, что это поможет.

person nontechguy    schedule 30.11.2018
comment
хорошо, кажется, что для одного matMenu вы показали только подробности о нем, а в другом меню вам нужно только перейти в профиль обновления и настройки учетной записи. Кстати, спасибо за код. Посмотрим, смогу ли я добиться этого на одном компоненте или нет. - person Maulik; 30.11.2018
comment
@non_tech_guy, огромное спасибо. Я постараюсь посмотреть на ваш ответ позже и дать обратную связь. ваше здоровье! - person Artanis Zeratul; 02.12.2018

Эта проблема связана со ссылками на элементы в angular, поэтому вы не можете напрямую использовать множественное меню mat в одном компоненте.

Уловка состоит в том, чтобы создать отдельный компонент, реализующий мат-меню: например,

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

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

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

Теперь вы можете использовать этот компонент несколько раз в любом компоненте. Например, app.component.html

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

Это будет работать.

person SAURABH SINGH    schedule 16.02.2021

У меня была такая же проблема, и я решил ее, используя свойство метаданных read декоратора @ViewChild.

mainmenu.component.html

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

mainmenu.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();
}

Хитрость заключается в том, чтобы использовать ссылку на шаблон menuBtn1 или menuBtn2 и указать через свойство read, что вы хотите получить, это директива MatMenuTrigger.

ПРИМЕЧАНИЕ. Я видел, что вопрос относится к angular и angular-material 5. Я тестировал его с angular 8, но он должен быть таким же

person Andrea R.    schedule 13.01.2021

person    schedule
comment
Для полноты полезно объяснить, почему и как это решает проблему. - person Mike; 08.03.2019