Components: mat-menu generation using dynamic data not showing arrow and nested sub-menus on hover

Created on 5 Jul 2019  路  13Comments  路  Source: angular/components

Reproduction

I am trying to generate n-level nested mat-menu using dynamic data,

If you repeat the reproduction steps with static html you will get the same issue.

here is theStackBlitz https://stackblitz.com/edit/angular-dlzv3q-fofemy

Steps to reproduce:

  1. wrap mat-menu-item in a ng-template outside of mat-menu
  2. use ng-container with ngTemplateOutlet inside mat-menu to render template created in step 1

Expected Behavior

mat-menu should display the arrow for nested mat-menu and on hover it should display the nested mat-menu

Actual Behavior

mat-menu is showing only top-level mat-menu-items without arrow and hover behavior, but on clicking an mat-menu-item(which have nested menu) main menu closes and nested menu opens up..

Environment

  • Angular: 8.1.0
  • CDK/Material: 8.0.2
  • Browser(s): Chrome
  • Operating System: Windows
materiamenu

Most helpful comment

To everyone looking for dynamic menus in angular 8 i made a working example:
https://stackblitz.com/edit/dynamic-material-menu-angular-8

All 13 comments

Im having the exaclty same issue. Couldnt find a away to avoid that.

Same here. It works correctly back in angular/components 8.0.1. Have the same issue even with angular/components 8.1.0.

I started encountering the bug with 8.1.0. For me the arrows display, but I have to click on the menu-item for the submenu to display. Another difference is that the original/main menu remains displayed.

Could the failures in the dynamic cases be due the move to @ContentChildren(MatMenuItem, {descendants: true}) in #11720 for mat-menu and/or mat-menu-item?

Thoughts @crisbeto?

Just noticed #16502 reverted the changes. Simply hasn't been released yet.

The PR to revert this was closed without being merged. I'm not sure where things stand.

Same problem... Any other way to create dynamic menus as of now? We cant upgrade to the new version due to this problem...

Dynamic menus are also not functioning properly for me. I am using this concept: https://stackblitz.com/edit/dynamic-nested-topnav-menu but I'm on Angular Material 8.1.3.

Navigation Component:

<nav fxLayout="row" fxLayoutGap="1em">
  <ng-container *ngIf="_navItems$ | async as navItems">
    <ng-container *ngFor="let item of navItems">
      <!-- Handle branch node buttons here -->
      <ng-container *ngIf="item.items && item.items.length > 0">
        <a mat-button [matMenuTriggerFor]="menu.childMenu">
          {{item.title}}
        </a>
        <app-menu-item #menu [items]="item.items"></app-menu-item>
      </ng-container>
      <!-- Leaf node buttons here -->
      <ng-container *ngIf="!item.items || item.items.length === 0">
        <a mat-button>
          {{item.title}}
        </a>
      </ng-container>
    </ng-container>
  </ng-container>
</nav>

Menu Item Component:

<mat-menu #childMenu="matMenu" [overlapTrigger]="false">
  <ng-container *ngFor="let child of items">
    <!-- Handle branch node menu items -->
    <ng-container *ngIf="child.items && child.items.length > 0">
      <button mat-menu-item color="primary" [matMenuTriggerFor]="menu.childMenu">
        {{child.title}}
      </button>
      <app-menu-item #menu [items]="child.items"></app-menu-item>
    </ng-container>
    <!-- Handle leaf node menu items -->
    <ng-container *ngIf="!child.items || child.items.length === 0">
      <button mat-menu-item>
        {{child.title}}
      </button>
    </ng-container>
  </ng-container>
</mat-menu>

For me, the top level menu is staying open on each click of a top level item. So I end up with a bunch of mat-menus open at one time. Possibly related to this pull request: https://github.com/angular/components/pull/15373

image

So far, whoever requires dynamic menu nesting is stuck with 8.0.x.

This directly affects the library I developed for that very purpose ng-action-outlet(@ng-action-outlet/core and @ng-action-outlet/material). Feel free to use it.


Official statement: https://github.com/angular/components/issues/17073#issuecomment-548459282

To everyone looking for dynamic menus in angular 8 i made a working example:
https://stackblitz.com/edit/dynamic-material-menu-angular-8

@Harpush yes this works, I already use it in my library, but it's not flexible enough. It works perfectly fine with direct menu nesting, however if in the middle of mat-menu-item you wanna have any other component it will break (This is required for ng-action-outlet).

I will try to refactor it completely to make it run again on 8.1.x, I do hope however Material will not change it in a month again :)

I managed to update ng-action-outlet above Material ~8.1.0. This required a substantial refactoring though.

If you're writing your own component to render menus dynamically, the key is to maintain the direct menu nesting between mat-menu and mat-menu-item, without any components in between, due to that recent material change of querying for direct children only.

Example from @Harpush demonstrates this nicely: https://github.com/angular/components/issues/16457#issuecomment-548547659


Anyone interested in a library, here are the usage examples:

Edit @ng-action-outlet/material DEMO

Edit @ng-action-outlet/material DEMO

As mentioned above, this doesn't work because the menu items are defined outside the menu. Closing since there are ways around it above. Also this is how the framework works and we can't do much about it.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

savaryt picture savaryt  路  3Comments

MurhafSousli picture MurhafSousli  路  3Comments

jelbourn picture jelbourn  路  3Comments

theunreal picture theunreal  路  3Comments

crutchcorn picture crutchcorn  路  3Comments