Как да се абонирам за излъчвател на събития веднъж?

// 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/ въпроси/44464655/   -  person Rolando    schedule 10.06.2017


Отговори (2)


Обаждане до subscribe връща екземпляр на Disposable, който има метод dispose.

Или ако използвате 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
В RxJS 5 dispose беше преименуван на unsubscribe - person Eric Martinez; 17.01.2016
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