如何订阅一次事件发射器?

Posted

技术标签:

【中文标题】如何订阅一次事件发射器?【英文标题】:How to subscribe to event emitter once? 【发布时间】:2016-04-22 16:46:39 【问题描述】:
// Part of service
public someEvent: EventEmitter<number> = new EventEmitter();

....

// Component
@Component(
  selector: 'some-component',
  template: `...`
)
export class SomeComponent 
  constructor(public service: Service) 
    this.service.someEvent.subscribe((x) => 
      // Do something
    );
  

SomeComponent 显示在/ 路由中。当我导航到应用程序中的不同路线并再次返回时,SomeComponent 将再次订阅该事件,导致回调触发两次。如何订阅一次事件或在组件销毁时取消订阅并重新订阅?

// Can't subscribe after.
ngOnDestroy() 
  this.service.someEvent.unsubscribe();

【问题讨论】:

你用 ngOnInit 试过了吗? @micronyks 是的,我做到了,但没有成功。同样根据this site ngOnInit 每次都会像构造函数一样被触发,但它等待子组件初始化。 OnInit 用于绑定,不适合你...试试CanReuse EventEmitter 应该在服务中使用,但仅用于 @Output()s 的组件和指令。请改用ObservableSubject 就我而言,在我导航另一条路线并再次返回后,订阅未触发,我无法解决。我在“NgOnInit”方法上使用它,并且在“NgOnDestroy”方法上也有取消订阅方法 【参考方案1】:

subscribe 的调用返回一个instance of Disposable,它有一个方法dispose

或者,如果您使用的是 RxJS 5,dispose has been renamed to unsubscribe(感谢 @EricMartinez)。

来自RxJS docs:

...当我们不再对接收流入的数据感兴趣时,我们在订阅上调用 dispose。


将调用结果存储到subscribe,然后在ngOnDestroy 中处理订阅。

RxJS 5:

export class SomeComponent 
  constructor (public service: Service) 
    this.subscription = this.service.someEvent.subscribe((x) => ...);
  
  ngOnDestroy () 
      this.subscription.unsubscribe();
  

RxJS

export class SomeComponent 
  constructor (public service: Service) 
    this.subscription = this.service.someEvent.subscribe((x) => ...);
  
  ngOnDestroy () 
      this.subscription.dispose();
  

【讨论】:

在 RxJS 5 dispose was renamed to unsubscribe 谢谢!就像@EricMartinez 说的,unsubscribe 而不是dispose 我在事件发射器触发 1、2、3 次或更多次时遇到了同样的问题。但是,当我向 ngOnDestroy 添加取消订阅时,我得到“ObjectUnsubscribedError”:( 没关系:我通过这样做修复它 this.subscription = this.service.someEvent.subscribe((x) => ...);在构造函数中【参考方案2】:

你可以这样做:

import  OnDestroy  from '@angular/core';
import  Subscription  from 'rxjs/Rx';

export class SomeComponent implements OnDestroy 
  private _subscription: Subscription;
  constructor(public service: Service) 
    this._subscription = this.service.someEvent.subscribe((x) => 
      // Do something
    );
  


ngOnDestroy()
  this._subscription.unsubscribe();

【讨论】:

以上是关于如何订阅一次事件发射器?的主要内容,如果未能解决你的问题,请参考以下文章

订阅的角度限制发射

js 事件发布订阅销毁

Rxswift 在事件发生时取消观察者并重新订阅

订阅所有 paypal webhooks 事件

小程序中发布订阅的最优解

RxJava 手动发出项目