2017-06-14 1 views
0

Entschuldigung, wenn dies trivial ist.Mit 2 oder mehr Komponenten abonnieren Sie eine kalte Observable zur Verfügung gestellt von einem Injizierbaren

Ich bin neu in Angular 4 und ich kämpfe mit einem scheinbar einfachen Problem: mit 2 oder mehr Komponenten abonnieren Sie eine Observable von einem (Login) Injectable zur Verfügung gestellt.

Mein Ziel ist es zu haben:

  1. Eine Ansicht, die ein Ereignis aufrufen auf component1
  2. component1 wird ein Verfahren auf einem login.service
  3. login.service aufrufen wird eine REST-Aufruf
  4. Die Antwort machen ist " Broadcast "mit einem .next()
  5. component1 und component2 wird re entsprechend handeln

Dies funktioniert perfekt, wenn es nur 1 Komponente ist, aber wenn ich eine andere Komponente einführen, die subscribe() s zum Observable, nur die zweiten Komponente gleich am Anfang mitgeteilt wird (dh: sie erhält nur eine Nachricht), während component1 funktioniert weiterhin wie erwartet und empfängt alle Nachrichten.

habe ich anfangs Subject und BehaviorSubject mit der asObservable() Methode fiel dann aber zurück auf Ebene Observable mit ähnlichen Ergebnissen.

Hier ist ein Ausschnitt zeigen, zu helfen:

login.service:

@Injectable() 
export class LoginService { 

    private _loggedIn = new BehaviorSubject<booelan>(false); 
    public loggedIn$ = this._loggedIn.asObservable(); 


    login() { 
     // call API service 
     this._loggedIn.next(true); 
    } 
} 

component1:

@Component({ 
    selector: 'app-test1', 
    template: `<button (click)="login()"`, 
    providers: [ LoginService ] 
}) 

export class AppTest1Component { 
    subscription: Subscription; 
    observer: Observer; 

    constructor(private loginService: LoginService) {} 

    ngOnInit() { 
     this.subscription = this.loginService.loggedIn$.subscribe(
      state => { console.log('got event!', state); }, 
      error => { console.log('Error:', error)}, 
      () => { console.log('Complete'); } 
     ); 
    } 

    ngOnDestroy() { 
     this.subscription.unsubscribe(); 
    } 
} 

component2:

@Component({ 
    selector: 'app-test2', 
    template: `<button (click)="login()"`, 
    providers: [ LoginService ] 
}) 

export class AppTest2Component { 
    subscription: Subscription; 
    observer: Observer; 

    constructor(private loginService: LoginService) {} 

    ngOnInit() { 
     this.subscription = this.loginService.loggedIn$.subscribe(
      state => { console.log('got event!', state); }, 
      error => { console.log('Error:', error)}, 
      () => { console.log('Complete'); } 
     ); 
    } 

    ngOnDestroy() { 
     this.subscription.unsubscribe(); 
    } 
} 

Was ist der einfachste Weg, um mehrere Komponenten zu abonnieren Observable, die vermutlich von einem Dienst zur Verfügung gestellt werden, und alle Nachrichten erhalten?

Die Frage hier gepostet: Angular - shared service between components doesn't work bezieht sich nicht auf Observables und Abonnements.

+0

Diese Frage steht möglicherweise nicht mit den Observablen in Zusammenhang, aber sie löst das gleiche Problem. Bitte lesen Sie die Antwort und versuchen Sie es in Ihrer App. – echonax

+0

Sie sind auf. Tut mir leid, dass ich mir die Zeit genommen habe, die Antwort gründlich zu lesen. Ich hatte Tunnelblick. – mstubbies

+0

Passiert das Beste von uns :-) – echonax

Antwort

0

Wie von echonax erklärt, scheint Ihr Problem mit this topic verwandt zu sein.

Durch das Hinzufügen von LoginService als Anbieter beider Komponenten erstellen Sie tatsächlich 2 Instanzen des genannten Dienstes.

@Component({ 
    selector: 'app-test2', 
    template: `<button (click)="login()"`, 
    providers: [ LoginService ] /* you are creating a new instance of the service here /* 
}) 

Wenn Sie die gleiche Instanz haben wollen, oder was für ein Shared-Service genannt wird, haben Sie den Anbieter in dem Modul sind sie in erklären und die Anbieter in den Komponenten entfernen:

@NgModule({ 
    ... 
    providers: [LoginService], 
    ... 
}) 

Wird durch Zufall die beiden Komponenten, die Sie in separaten Modulen erwähnt sind, haben Sie den Service als Anbieter in einem Modul zu erklären, und dann dieses Modul zum anderen importieren:

/* NgModule of the Module2 */ 
@NgModule({ 
    imports: [ 
    Module1], /* you import the module which has the service as provider */ 
    providers: [] /* Really important point here, you have to leave providers blank or at least with no reference to the shared service, or you will create a new instance of the said service */ 
    ... 
}) 

ich bin nicht ganz sicher, dass es Ihr Problem lösen würde, aber ich bin mir fast sicher, dass Sie in Ihrer App einen gemeinsamen Dienst verwenden müssen, basierend auf dem von Ihnen bereitgestellten Code.

+0

Sie sind beide richtig. Danke Echonax und nvkfr. Ich habe den ganzen Tag damit gekämpft. Ich hatte den Dienst bereits in meinen @NgModules deklariert, aber ich habe dummerweise eine neue Kopie in jeder Komponente instanziiert, wie Sie in meinen Schnipsel gesehen haben. Sobald ich die Provider von beiden Komponenten entfernt habe, hat alles perfekt funktioniert. DANKE! – mstubbies

Verwandte Themen