视图完全加载后如何从另一个组件调用方法(AppComponent)?
Posted
技术标签:
【中文标题】视图完全加载后如何从另一个组件调用方法(AppComponent)?【英文标题】:How to call a method from another component after view is fully loaded (AppComponent)? 【发布时间】:2019-01-17 02:52:15 【问题描述】:我在 HeaderComponent
中使用来自 Angular Material 的 MatMenu。我只需要在特定条件下(方法)打开菜单,在ProductDetailComponent
上调用这个方法。但是这个方法只在 ngAfterViewInit()
内部起作用,在视图加载之后。
我找到了一种从ProductDetailComponent
到HeaderComponent
的通信方式,但是有一个子父关系可以到达组件。 HeaderComponent
是从 AppComponent
调用的。
这里是应用组件
<my-header [openMenu]="clickBehavior"></my-header>
<router-outlet></router-outlet> <!-- ProductComponent -->
产品组件
<router-outlet></router-outlet> <!-- ProductDetailComponent -->
ProductDetail组件
export class ProductComponent
clickBehavior = new BehaviorSubject(null);
click()
this.clickBehavior.next(1);
ProductDetail 标记
<!-- i need to move it to app component
<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>
【问题讨论】:
你可以在stackblitz.com中添加你的代码 我想实现这个link,但是在AppComponent上使用这个结构<my-header [openMenu]="clickBehavior"></my-header> <router-outlet></router-outlet>
【参考方案1】:
您可以通过使用共享服务并在需要的地方注入服务来实现此目的。
设置一个共享服务,我设置了获取、设置和切换菜单状态的方法。
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>
【讨论】:
以上是关于视图完全加载后如何从另一个组件调用方法(AppComponent)?的主要内容,如果未能解决你的问题,请参考以下文章