Подтвердить что ты не робот

Как подписаться на событие эмиттер один раз?

// 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();
}
4b9b3361

Ответ 1

Вызов subscribe возвращает экземпляр Disposable, который имеет метод dispose.

Или, если вы используете RxJS 5, dispose был переименован в unsubscribe (спасибо @EricMartinez).

И из RxJS docs:

... когда мы больше не заинтересованы в получении данных по мере поступления данных, мы вызываем их в нашу подписку.


Сохраните результат своего вызова subscribe, а затем удалите подписку в ngOnDestroy.

RxJS 5:

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

RxJS < 5:

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

Ответ 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();
}