可观察,在 ngOnDestroy 中取消订阅不起作用

Posted

技术标签:

【中文标题】可观察,在 ngOnDestroy 中取消订阅不起作用【英文标题】:Observable, unsubscribe in ngOnDestroy not working 【发布时间】:2018-11-22 23:21:30 【问题描述】:

我有一个对话框打开并包含一个组件...在我订阅的组件中。关闭时我想退订..

private deviceObserver: Observable<BreakpointState> = this.breakpointObserver.observe([Breakpoints.XSmall]);

this.deviceObserver.subscribe(result => 
  if (result.matches) 
    this.deviceType = 'mobile';
   else 
    this.deviceType = 'desktop';
  
);

ngOnDestroy() 
 this.deviceObserver.unsubscribe();

这给了我这个错误:

“可观察”类型上不存在属性“取消订阅”。您指的是“订阅”吗?

【问题讨论】:

首先您必须订阅,将其分配给一个变量,然后您可以取消订阅。 【参考方案1】:

您只能在Subscription 上使用unsubscribe。您正在尝试在 Observable 上使用它。

如果您使用 async 管道在组件内部使用 observable,则无需取消订阅。这是由框架自动完成的。

但是,如果您在 component.ts 中使用它,那么一种方法就是这样做。还有其他选项,例如使用 takeUntil 管道:

private deviceObserver: Observable<BreakpointState> = 
                        this.breakpointObserver.observe([Breakpoints.XSmall]);

ngOnInit() 
  this.sub = this.deviceObserver.subscribe(result => 
    if (result.matches) 
      this.deviceType = 'mobile';
     else 
      this.deviceType = 'desktop';
    
  );


ngOnDestroy() 
 this.sub.unsubscribe();

【讨论】:

我已经尝试过了,但是这破坏了功能..做了一些更多的挖掘,如果我在 ngOnDestroy 中这样做它会中断..所以我将取消订阅移动到 closeDialog 方法并且效果很好! :) 这似乎不太可能。您的代码在 observable 上使用 unsubscribe,您不应该这样做:) 但可以安全地引用订阅(或使用 takeUntil) 查看我更新的问题(缺少代码哈哈).. 还发布了工作代码作为答案。我认为当我打开 cdk 的 OverlayRef 并将组件附加到 ComponentPortal 时出现问题 您的答案中的代码使用订阅参考,您的问题中的代码没有。我看不出为什么在 ngOnDestroy 中使用订阅引用不起作用 好吧,但 document.addEventListener('keydown'... 代码只在我添加 ngOnDestroy 时的第一个键下有效(有或没有订阅/取消订阅)【参考方案2】:

出于某种原因,在 ngOnDestroy 中取消订阅会破坏应用程序...这就是我解决它的方法:

private deviceObserver: Observable<BreakpointState> = this.breakpointObserver.observe([Breakpoints.XSmall]);
private breakpointObserverSubscription: Subscription;


// in ngOnInit()
this.breakpointObserverSubscription = this.deviceObserver.subscribe(result => 
  if (result.matches) 
    this.deviceType = 'mobile';
   else 
    this.deviceType = 'desktop';
  
);

public closeSearch() 
 this.onClose.apply();
 this.breakpointObserverSubscription.unsubscribe();

【讨论】:

以上是关于可观察,在 ngOnDestroy 中取消订阅不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 takeUntil 和 combineLatest 取消订阅可观察的 rxjs 不起作用

如何取消订阅路由解析类中的可观察对象

服务中的 Angular 4+ ngOnDestroy() - 销毁 observable

嵌套可观察订阅问题,无法取消订阅

如何取消订阅角度组件中的多个可观察对象?

组件 ngOnInit 中的 Angular 订阅