我知道这篇文章发布在SO和互联网上,但我读了很多不同的东西,我现在只是有点困惑。
2个问题-
- 订阅我的组件constructor((或NgOnInit((的最佳位置在哪里
- 我应该在订阅Observable时使用管道,这样Angular就可以销毁它,还是不必使用ngondestroy?有点困惑,为什么订阅后会有管道
这里是我的一个服务的例子,在我的导航栏组件中,我订阅了侦听来自服务的窗口大小更改。
在我的构造函数中,我有这个-
this.responsiveService.getMobileStatus()
.subscribe(mobileStatus => {
this.isMobile = mobileStatus.status;
if (mobileStatus.width < 568) {
this.inputPlaceholder = this.placeholderWithSearch;
} else {
this.inputPlaceholder = this.placeholderWithoutSearch;
}
});
-
使用
ngOnInit
进行订阅是一种很好的做法,因为@Input
绑定在这个生命周期挂钩之前还没有初始化,所以它们在构造函数中还没有准备好,而且通常可观察值可能取决于这些值。即使他们不这样做,保持一致并始终在同一个地方也是一件很好的练习。 -
只要可行,就应该使用
async
管道来避免手动订阅管理,但这并不总是可能或合理的。
我认为最好使用async
管道,并让angular处理取消订阅。它产生更干净的代码;
让我们考虑一下订阅在构造函数中的代码
export class MyClassComponent implements OnInit, OnDestroy {
sub: any;
componentName: any;
constructor(private navbarService: NavbarService) {
}
ngOnInit() {
this.sub = this.navbarService.getComponentNameObv()
.subscribe(componentName => {
this.componentName = componentName;
});
}
ngOnDestroy() {
this.sub.unsubscribe()
}
}
使用async
管道,我们可以重构
export class MyClassComponent {
componentName$ = this.navbarService.getComponentNameObv();
mobileStatus$ = this.responsiveService.getMobileStatus().pipe(
tap(mobileStatus => {
this.isMobile = mobileStatus.status;
if (mobileStatus.width < 568) {
this.inputPlaceholder = this.placeholderWithSearch;
} else {
this.inputPlaceholder = this.placeholderWithoutSearch;
}
})
)
constructor(private navbarService: NavbarService) {
}
}
代码要短得多,也更容易测试