2016-01-22 1 views
1

D'une manière par des événements, d'autres par des méthodes d'appel. J'essaie de réaliser un motif agrégé dans mon application.Comment deux services peuvent-ils communiquer les uns avec les autres de manière bidirectionnelle?

J'ai AuthService, ici je gère les résultats d'authentification et j'émets l'événement.

if (auth) { this.eAuth.emit(true) } else { this.eAuth.emit(false) } 

Je peux souscrire à Auth

_authService.eAuth.subscribe((isAuth) => this.handleAuthResult(isAuth)) 

Et il fonctionne parfaitement. Mais AggregateService doit également le savoir et diffuser ces informations sur UserService, LoadDataService, etc.

Comment le faire? Upd: mon agrégatService n'a pas de composant et j'injecte déjà AuthService dans celui-ci.

+1

EventEmitter n'a pas seulement le travail entre le service et le composant, ils sont réellement utiles entre les composants, un composant peut réagir à un événement émis par un autre composant et appeler un autre service quand il arrive. – Langley

+0

Mon agrégatService n'a pas de composant. – ivanesi

+0

Vous pouvez injecter un service dans un autre service et l'appeler quand vous le voulez, vous n'avez pas besoin d'utiliser EventEmitters. – Langley

Répondre

4

Si ServiceA est injecté dans Serviceb, Serviceb peut appeler des méthodes sur ServiceA (donc Serviceb → de communication ServiceA) et il peut subscribe() à tout Obervable que ServiceA pourrait exposer (d'où ServiceA → à la communication Serviceb).

Ce qui manque, c'est la capacité de ServiceA à appeler directement des méthodes sur ServiceB. Ceci est souvent déconseillé, car il crée un couplage entre les services. ServiceA doit émettre des événements en utilisant next() sur l'Observable que ServiceB peut subscribe() à, puis ServiceB peut appeler la (s) méthode (s) appropriée (s) sur lui-même.

Toutefois, si vous avez vraiment besoin de cela, voici une façon de le faire: ServiceB appelle une méthode registerService(this) sur ServiceA. Le type de l'argument devrait être une interface plutôt qu'un type concret, pour limiter le couplage. Alors ServiceA aura une référence à ServiceB et il peut appeler des méthodes dessus.

interface SomeInterface { 
    public methodOne(); 
    public methodTwo(); 
} 

import {SomeInterface} from './some-interface'; 
export class ServiceA { 
    registerService(someService:SomeInterface) { 
     someService.methodOne(this); 
     // you'll probably want to store someService in this object 
    } 
} 

Serviceb doit implement cette interface - à savoir, mettre en œuvre l'ensemble des méthodes qui ServiceA peut appeler.

import {SomeInterface} from './some-interface'; 
export class ServiceB implements SomeInterface { 
    constructor(private _serviceA: ServiceA) { 
     _serviceA.registerService(this); 
    } 
    methodOne(who) { 
     console.log('hello from ServiceB.methodOne(), called by', who); 
    }   
    methodTwo() { ... } 
} 

Plunker

+0

Vous avez dit que "Si ServiceA est injecté dans ServiceB, il peut subscribe() à n'importe quel EventEmitters que ServiceA pourrait exposer". ServiceA est également injecté dans ServiceC. Méthode d'appel ServiceB de ServiceA → ServiceA émission d'événement → Je peux m'abonner à ServiceB et cela fonctionne (mais pas nécessaire). Je dois m'abonner à ServiceC, mais je n'arrive pas à le faire fonctionner. http://plnkr.co/edit/b4W09zOqoOLUgI3DRvDv – ivanesi

+0

@ivanesi, il y avait beaucoup de problèmes avec votre plunker. Je crois que je les ai fixés ... jetez un oeil à [ce plunker] (http://plnkr.co/edit/TfsHY79aTxngWiKBWeZt?p=preview). –

+0

merci pour votre aide – ivanesi