我在“ Header Component”中使用了来自Angular Material的MatMenu。我只需要在特定条件下打开菜单即可。但是,此方法仅在加载视图后才能在ngAfterViewInit()内部使用。
export class HeaderComponent implements AfterViewInit {
@ViewChild('triggerCart') trigger: MatMenuTrigger;
ngAfterViewInit() {
this.openMenu();
}
openMenu() {
this.trigger.openMenu();
}
}
<button mat-button
[matMenuTriggerFor]="shoppingCartMenu"
#triggerCart="matMenuTrigger"
(menuOpened)="isOpened($event)"
(mouseenter)="largeScreen ? triggerCart.openMenu() : ''">
</button>
我需要从其他组件调用此方法,但是ngAfterViewInit之外的Menu触发器未定义。
<button mat-stroked-button
(click)="someMethod()">
</button>
export class ProductDetailComponent {
@ViewChild(HeaderComponent) header: HeaderComponent;
someMethod() {
this.header.openMenu();
}
}
在加载了Header Component之后如何实现组件之间的通信?
答案 0 :(得分:1)
这是一种实现方法的示例(但不一定是最佳方法)。是要提供组件之间交互的概念。
产品组件
export class ProductComponent {
clickBehavior = new BehaviorSubject(null);
click() {
this.clickBehavior.next(1);
}
}
产品标记
<my-header [openMenu]="clickBehavior"></my-header>
<div>
<button (click)="click()">Click</button>
</div>
标题组件
export class HeaderComponent implements AfterViewInit {
@ViewChild('trigger') trigger: MatMenuTrigger;
@Input() openMenu: Observable<any>;
ngAfterViewInit() {
this.openMenu.subscribe(value => {
if (value) {
this.trigger.openMenu();
}
});
}
}
标题标记
<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>
这个想法是触发Header组件的输入,这是通过使用Product组件中的BehaviorSubject来完成的。
参考:
答案 1 :(得分:0)
您可以通过使用共享服务并将其注入到需要的位置来实现此目的。
设置共享服务,我放置获取,设置和切换菜单状态的方法。
注意:为了对此进行动画处理,因为它使用ngIf,您将需要使用角度动画。
SharedService.ts
import { Injectable } from '@angular/core';
@Injectable()
export class SharedService {
//The current menu state
private showMenu_ = false;
//get the current menu state
get showMenu() {
return showMenu_;
}
//set the menu state
set showMenu(state: boolean) {
this.showMenu_ = state;
}
//toggle the menu
public toggleMenu() {
this.showMenu_ = !this.showMenu;
}
}
将服务注入appComponent,以便我们可以使用它控制菜单状态。
appComponent.ts
import { SharedService } from 'PATH TO SHARED SERVICE';
...
constructor(public sharedService: SharedService){}
根据sharedService中设置的状态将my-header设置为显示/隐藏。
appComponent.html
<my-header *ngIf="sharedService.showMenu"></my-header>
将服务注入到其他任何组件/页面中,以更改菜单的状态。 在这种情况下为ProductComponent.ts。
ProductComponent.ts
import { SharedService } from 'PATH TO SHARED SERVICE';
...
constructor(public sharedService: SharedService){}
ProductComponent.html
<div>
<button (click)="sharedService.toggleMenu()">Click</button>
</div>
或与BehavourSubject一起使用。
在SharedService中创建BehaviorSubject。
import { Injectable } from '@angular/core';
@Injectable()
export class SharedService {
//The current menu state
private showMenu_ = false;
private showMenu$: BehaviorSubject<boolean> = new
BehaviorSubject(false);
//get a reference to showMenu$ for subscription
public menuState() {
return showMenu$;
}
//Change menu state to show.
public showMenu(){
this.showMenu_ = true;
this.showMenu$.next(this.showMenu_);
}
//Change menu state to hide.
public hideMenu(){
this.showMenu_ = false;
this.showMenu$.next(this.showMenu_);
}
//Toggle menu state.
public toggleMenu(){
this.showMenu_ = !this.showMenu;
this.ShowMenu$.next(this.showMenu_);
}
//get the current menu state.
public getMenuState() {
return this.showMenu$.getValue();
}
将服务注入到appComponent中,以便我们可以订阅菜单状态。
appComponent.ts
import { SharedService } from 'PATH TO SHARED SERVICE';
...
export class appComponent implements OnInit, OnDestroy {
//variable used to show/hide the menu.
public showMenu;
//reference to subscription so we can unsubscribe later.
private this.menuStateSub: Subscription;
constructor(public sharedService: SharedService){}
ngOnInit() {
//subscribe to the menuState BehaviorSubject
this.menuStateSub = this.sharedService.menuState().subscribe((state)=>{
this.showMenu = state;
})
}
ngOnDestroy() {
//unsubscribe before leaving the page
this.menuStateSub.unsubscribe();
}
根据sharedService中设置的状态将my-header设置为显示/隐藏。
appComponent.html
<my-header *ngIf="sharedService.showMenu"></my-header>
最后将服务注入到我们需要控制菜单状态的位置。
ProductComponent.ts
import { SharedService } from 'PATH TO SHARED SERVICE';
...
constructor(public sharedService: SharedService){}
,现在我们可以使用该服务来切换状态。 ProductComponent.html
<div>
<button (click)="sharedService.toggleMenu()">Click</button>
</div>