web-dev-qa-db-fra.com

Comment s'inscrire à un événement sur un service dans Angular2?

Je sais comment soulever un événement avec EventEmitter. Je peux aussi attacher une méthode à appeler si j'ai un composant comme celui-ci:

<component-with-event (myevent)="mymethod($event)" />

Quand j'ai un composant comme celui-ci, tout fonctionne très bien. J'ai transféré une certaine logique dans un service et je dois créer un événement depuis l'intérieur du service. Ce que j'ai fait était ceci:

export class MyService {
  myevent: EventEmitter = new EventEmitter();

  someMethodThatWillRaiseEvent() {
    this.myevent.next({data: 'fun'});
  }
}

J'ai un composant qui doit mettre à jour une valeur en fonction de cet événement, mais je n'arrive pas à le faire fonctionner. Ce que j'ai essayé était ceci:

//Annotations...
export class MyComponent {
  constructor(myService: MyService) {
    //myService is injected properly and i already use methods/shared data on this.
    myService.myevent.on(... // 'on' is not a method <-- not working
    myService.myevent.subscribe(.. // subscribe is not a method <-- not working
  }
}

Comment faire pour que MyComponent s'abonne à l'événement lorsque le service qui le déclenche n'est pas un composant?

Je suis sur le 2.0.0-alpha.28

EDIT: Modifié mon "exemple de travail" pour qu'il fonctionne réellement, pour que l'accent soit mis sur la partie qui ne fonctionne pas;)

Exemple de code: http://plnkr.co/edit/m1x62WoCHpKtx0uLNsIv

93

Mise à jour : J'ai trouvé un moyen meilleur/approprié de résoudre ce problème en utilisant un BehaviorSubject ou un Observable plutôt qu'un EventEmitter. Veuillez voir cette réponse: https://stackoverflow.com/a/35568924/215945

De plus, les documents Angular _ ont maintenant un exemple de livre de recettes utilisant un objet .


Réponse originale/obsolète/incorrecte: à nouveau, n'utilisez pas un EventEmitter dans un service . C'est un anti-modèle.

Using beta.1 ... NavService contient EventEmiter. Component Navigation émet des événements via le service, et le composant ObservingComponent souscrit aux événements.

nav.service.ts

import {EventEmitter} from 'angular2/core';
export class NavService {
  navchange: EventEmitter<number> = new EventEmitter();
  constructor() {}
  emitNavChangeEvent(number) {
    this.navchange.emit(number);
  }
  getNavChangeEmitter() {
    return this.navchange;
  }
}

composants.ts

import {Component} from 'angular2/core';
import {NavService} from '../services/NavService';

@Component({
  selector: 'obs-comp',
  template: `obs component, item: {{item}}`
})
export class ObservingComponent {
  item: number = 0;
  subscription: any;
  constructor(private navService:NavService) {}
  ngOnInit() {
    this.subscription = this.navService.getNavChangeEmitter()
      .subscribe(item => this.selectedNavItem(item));
  }
  selectedNavItem(item: number) {
    this.item = item;
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

@Component({
  selector: 'my-nav',
  template:`
    <div class="nav-item" (click)="selectedNavItem(1)">nav 1 (click me)</div>
    <div class="nav-item" (click)="selectedNavItem(2)">nav 2 (click me)</div>
  `,
})
export class Navigation {
  item = 1;
  constructor(private navService:NavService) {}
  selectedNavItem(item: number) {
    console.log('selected nav item ' + item);
    this.navService.emitNavChangeEvent(item);
  }
}

Plunker

116
Mark Rajcok

En utilisant l'alpha 28, j'ai pu m'abonner par programme aux émetteurs d'événements à l'aide de la méthode eventEmitter.toRx().subscribe(..). Comme ce n’est pas intuitif, cela pourrait peut-être changer dans une prochaine version.

4
Runeboy