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

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

person Eggy    schedule 17.01.2016    source источник
comment
Вы пробовали это с ngOnInit?   -  person micronyks    schedule 17.01.2016
comment
@micronyks Да, но безуспешно. Также согласно этот сайт ngOnInit запускается каждый раз, как функция конструктора, но ожидает инициализации дочерних компонентов. .   -  person Eggy    schedule 17.01.2016
comment
OnInit предназначен для привязки, не сработает для вас ... попробуйте CanReuse   -  person Sasxa    schedule 17.01.2016
comment
EventEmitter не предполагается использовать в службах, а только для @Output() компонентов и директив. Вместо этого используйте Observable или Subject.   -  person Günter Zöchbauer    schedule 28.09.2016
comment
В моем случае после того, как я перейду по другому маршруту и ​​вернусь снова, подписка не срабатывает, что я не мог решить. Я использую его в методе NgOnInit, а также имею метод отказа от подписки в методе NgOnDestroy.   -  person İsmail Şener    schedule 16.03.2017
comment
У меня аналогичная проблема .. но все еще используя функцию отписки, проблема существует. stackoverflow.com/ questions / 44464655 /   -  person Rolando    schedule 10.06.2017


Ответы (2)


Вызов subscribe возвращает экземпляр Disposable, у которого есть метод _ 3_.

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

И из документов RxJS:

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


Сохраните результат вашего обращения к 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();
  }
}
person sdgluck    schedule 17.01.2016
comment
comment
Спасибо! Как сказал @EricMartinez, unsubscribe вместо dispose. - person Eggy; 17.01.2016
comment
У меня такая же проблема с эмиттером событий, срабатывающим 1, 2, 3 или более раз. Однако когда я добавляю отписку в ngOnDestroy, я получаю ObjectUnsubscribedError :( - person brando; 12.04.2016
comment
Неважно: я исправил это, выполнив this.subscription = this.service.someEvent.subscribe ((x) = ›{...}); в конструкторе - person brando; 12.04.2016

Вы можете сделать что-то вроде этого:

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();
}
person ShellZero    schedule 27.09.2016