angular - Angular2+/Rxjs Observable 构造函数/ngOnInit - 路由 onPageChange
问题描述
我面临可观察和组件生命周期的问题。这是一个虚拟的stackBlitz:
https://stackblitz.com/edit/angular-ivy-tpytgx
我需要在每个 pageChange 上触发不同组件上的一些特定方法。
ngOnInit() {
this.actionsOnRouteChange();
}
actionsOnRouteChange() {
this.router.events.subscribe(event => {
if (!(event instanceof NavigationEnd) || typeof window === 'undefined') {
return;
}
this.myService.pageChange();
});
}
}
最初我有一个这样的代码,但我很挣扎,因为pageChanged$
没有取消订阅,所以在根本没有加载组件的页面上也被触发。
ngOnInit(){
this.myService.pageChanged$
.subscribe(() => this.myService.printOnConsole('Hello there!' + this.name))
}
所以我以这种方式更改了代码。
subscriptionAlive = true;
constructor(
private myService: MyService
) {
}
ngOnInit(){
this.myService.pageChanged$
.pipe(
takeWhile(() => {
console.log('alive', this.subscriptionAlive);
return this.subscriptionAlive})
)
.subscribe(() => this.myService.printOnConsole('Hello there!' + this.name))
}
ngOnDestroy(){
this.subscriptionAlive = false;
}
现在我解决了前面的问题,订阅的回调根本没有被触发,我怀疑这是因为pageChanged$在组件加载之前发出,所以订阅部分还没有初始化。出于这个原因,我以这种方式将订阅移动到构造函数中:
constructor(
private myService: MyService
) {
this.myService.pageChanged$
.pipe(
takeWhile(() => {
console.log('alive', this.subscriptionAlive);
return this.subscriptionAlive})
)
.subscribe(() => this.myService.printOnConsole('Secret Info!'))
}
现在它就像一个魅力,但直到我不需要从他的父级传递组件@Input
,我们知道在构造函数中尚未初始化。
在 StackBlitz 中,informationComponent是在没有任何数据传递的情况下工作良好的组件,@Input
而helloComponent是需要使用从父组件传递的数据但工作不正常的组件。
我也尝试过ngOnChanges
,我也玩过,BehaviorSubject
但没有成功。
我错过了什么??
谢谢!
更新 1
我将每个组件的所有订阅都移回ngOnInit
并更改Subject<boolean>()
为BehaviorSubject<boolean>(null)
,现在它正在工作,但我遇到了另一个问题,我试图在 StackBlitz 上重现但没有成功。在我的真实应用程序中,使用装饰器的组件 (ListMeComponent)@ViewChild
似乎调用了发射器两次,如果订阅的代码只在 stackBlitz 中写入,则一次又一次ngOnInit
。afterViewInit
afterViewInit
更新 2
我解决了@ViewChild
装饰器设置的问题{ static: true }
以便能够使用它ngOnInit
,然后我发现它BehaviorSubject
被触发了两次,这是他的正常行为,因为如果发射为空,它也会起作用,因为我需要SubjectBehavior
解决发射值true
并将管道过滤器添加到订阅。
private pageChanged = new BehaviorSubject<boolean>(null);
pageChanged$ = this.pageChanged.asObservable();
pageChange() {
this.pageChanged.next(true);
console.log('pageChanged emitted');
}
this.myService.pageChanged$
.pipe(
takeWhile(() => this.subscriptionAlive),
filter(isTrue => isTrue)
)
.subscribe(() =>
this.myService.printOnConsoleList(
'List',
this.mobileOccasions.nativeElement.offsetParent !== null
)
);
我还更新了 stackblitz。
解决方案
推荐阅读
- python - 具有产量的自定义 Keras 数据生成器
- php - 在刀片模板中捕获“试图获取非对象的属性”
- python - DataFrame:查找指定行并将数值赋给同一行的另一列
- java - G1GC 的内存使用具有误导性
- mysql - 为什么在 MySQL 中使用 DES_DECRYPT 函数时密钥似乎不起作用?
- kendo-ui - 使用多选 Kendo 过滤数据源
- electron - NWJS,Electron - DOM 在长时间运行过程中不更新
- python - 是否有类似于 Pandas 的 df.combine_first 的 pyspark 函数?
- asp.net-core - 引用 .NET 项目的 ASP.NET Core 项目无法使用 msbuild 构建
- angular - 有没有办法向 proxy.config.json 添加注释?