I'm using MatMenu from Angular Material inside HeaderComponent
. I just need to open the Menu under certain conditions (method), calling this method on ProductDetailComponent
. However this method only works inside ngAfterViewInit()
, after the view is loaded.
I found a way to comunicate from ProductDetailComponent
to HeaderComponent
, however there is a Children-Parent relationship to reach the components. HeaderComponent
is called from AppComponent
.
Here is AppComponent
<my-header [openMenu]="clickBehavior"></my-header>
<router-outlet></router-outlet> <!-- ProductComponent -->
ProductComponent
<router-outlet></router-outlet> <!-- ProductDetailComponent -->
ProductDetail component
export class ProductComponent {
clickBehavior = new BehaviorSubject(null);
click() {
this.clickBehavior.next(1);
}
}
ProductDetail markup
<!-- i need to move it to app component
<my-header [openMenu]="clickBehavior"></my-header>
-->
<div>
<button (click)="click()">Click</button>
</div>
Header component
export class HeaderComponent implements AfterViewInit {
@ViewChild('trigger') trigger: MatMenuTrigger;
@Input() openMenu: Observable<any>;
ngAfterViewInit() {
this.openMenu.subscribe(value => {
if (value) {
this.trigger.openMenu();
}
});
}
}
Header markup
<button mat-button
[matMenuTriggerFor]="menu"
#trigger="matMenuTrigger">Menu
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
You can achieve this by using a shared service and injecting the service where it is required.
Setup a shared service, i put methods to get, set and toggle the menu state.
SharedService.ts
Inject the service into appComponent so we can control the menu state with it.
appComponent.ts
Set my-header to show/hide based on the state set in the sharedService.
appComponent.html
Inject the service into any other component/page to change the state of the menu. In this case ProductComponent.ts.
ProductComponent.ts
ProductComponent.html
Or with BehavourSubject from service.
Create the BehaviorSubject in SharedService.
Inject the service into appComponent so we can subscribe to the menu state.
appComponent.ts
Set my-header to show/hide based on the state set in the sharedService.
appComponent.html
Finally inject the service where we need to control the menu state.
ProductComponent.ts
and now we can use the service to toggle the state. ProductComponent.html