Reputation: 19441
We want to split a large menu (e.g. like the Nested menu
example from the material components docs) into separate smaller components.
E.g. in this Stackblitz example we moved the fish menu to a separate component: fish-menu.component.ts:
import { Component } from "@angular/core";
@Component({
selector: "fish-menu",
template: `
<button mat-menu-item [matMenuTriggerFor]="fish">Fishes</button>
<mat-menu #fish="matMenu">
<button mat-menu-item>Baikal oilfish</button>
<button mat-menu-item>Bala shark</button>
<button mat-menu-item>Ballan wrasse</button>
<button mat-menu-item>Bamboo shark</button>
<button mat-menu-item>Banded killifish</button>
</mat-menu>
`
})
export class FishMenuComponent {}
And include it in the parent menu, like so:
<button mat-button [matMenuTriggerFor]="animals">Animal index</button>
<mat-menu #animals="matMenu">
<button mat-menu-item [matMenuTriggerFor]="vertebrates">Vertebrates</button>
<button mat-menu-item [matMenuTriggerFor]="invertebrates">Invertebrates</button>
</mat-menu>
<mat-menu #vertebrates="matMenu">
<!-- our child-component does not work as expected -->
<fish-menu></fish-menu>
<!-- other children are okay -->
<button mat-menu-item [matMenuTriggerFor]="amphibians">Amphibians</button>
<!-- etc. -->
But the included menu does not work as expected, when we hoover the menu item:
NOTE
We want to include the full menu in the child component: i.e. the button with matMenuTriggerFor
and the related mat-menu
(because the very same menu should be included in multiple places in the production app). And the parent menu is not always the same: i.e. we have many different parent-menus which are composed of different sub-menus.
How can we make this work as expected?
Upvotes: 1
Views: 1898
Reputation: 1771
I've run into this issue as well and this is caused by your child component not having the same context for matMenu
as your parent. To work around this I passed an object of my child menus to my parent through an input and built them dynamically.
If you are planning to have a single component that displays your matMenuTriggerFor
button I believe your solution should be much more straightforward. You can house your entire menu in a single component and use it in multiple other components.
I've done something like what you described here: https://stackblitz.com/edit/angular-me42ci-bbbnfz?file=src%2Fapp%2Fmenu-nested-example.html
EDIT
I came up with something that might work for you. You could pass in your top level menu items through ng-content:
<app-menu>
<button mat-menu-item>Aliens</button>
</app-menu>
menu.component.ts:
<mat-menu #animals="matMenu">
<ng-content></ng-content>
<button mat-menu-item [matMenuTriggerFor]="vertebrates">
Vertebrates
</button>
<button mat-menu-item [matMenuTriggerFor]="invertebrates">
Invertebrates
</button>
</mat-menu>
https://stackblitz.com/edit/angular-me42ci-bbbnfz?file=src%2Fapp%2Fmenu-nested-example.html
Upvotes: 2