我的一位同事问我是否需要取消订阅对话框的afterClosed()观察。
我们正在使用takeUntil模式来取消订阅ngOnDestroy()上的所有Observable。
this.backEvent = fromEvent(window, 'popstate')
.pipe(
takeUntil(this.destroy$)
)
.subscribe(
() => {
this.navigationService.backClicked = true;
this.navigationService.navigateBackToDirectoryCenter();
}
);
ngOnDestroy()
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
那么有必要取消对afterClosed()可观察的订阅吗?
dialogRef.afterClosed().subscribe(
(data) => {
console.log(data);
}
},
);
还是?
dialogRef.afterClosed()
.pipe(
takeUntil(this.destroy$)
)
.subscribe(
(data) => {
console.log(data);
},
);
答案 0 :(得分:2)
当订阅块使用 this.xxxx
组件属性时,您通常希望取消订阅 observable 以防止内存泄漏和错误。
即使订阅完成并且您不需要考虑内存泄漏,您也应该注意第二个问题。
调用 dialogRef.afterClosed()
的宿主组件可能会在对话框仍然可见时被破坏。订阅将在关闭后发出,当您访问订阅块内的组件属性时,它会抛出错误。
我认为这是一种罕见的情况,即在对话框处于活动状态时主机组件被破坏,但我想指出这种极端情况。 一个例子可能是一个浮动按钮,它打开一个对话框但在滚动或其他情况下消失。
答案 1 :(得分:1)
很好的问题,只是看了一下文档(https://material.angular.io/components/dialog/overview),似乎没有什么暗示完全需要退订,您已经拥有的就足够了。
答案 2 :(得分:1)
当可观察对象本身完成时,您无需取消订阅。您可以通过添加finalize块来验证可观察对象自身是否完成来进行验证。
import { finalize } from "rxjs/operators";
dialogRef
.afterClosed()
.pipe(finalize(() => console.log("completed")))
.subscribe(data => {
console.log(data);
});
当您关闭对话框时,您会在控制台中看到completed
,这表明您不需要取消订阅可观察对象。