Angular-DialogRef-退订-是否需要从afterClosed退订?

时间:2019-10-02 09:13:12

标签: angular rxjs unsubscribe

我的一位同事问我是否需要取消订阅对话框的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);
        },
    );

3 个答案:

答案 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,这表明您不需要取消订阅可观察对象。