2016-08-13 1 views
3

Ich habe einen Datendienst, der Abfragen über HTTP (ausgelöst durch eine Komponente) ausführt und dann die Ergebnisse über Observable darstellt. Andere Komponenten würden das Observable abonnieren und ihre Ansicht der Ergebnisse aktualisieren.RxJS/Angular2: Warum wird mein Betreff-Abonnent nicht aufgerufen?

Das ist die Idee, aber es funktioniert nicht. Hier ist mein Code.

ItemListDataService:

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable, Subject } from "rxjs"; 
import 'rxjs/add/operator/map'; 

@Injectable() 
export class ItemListDataService { 
    private issues$: Subject<any>; 

    constructor(private http: Http) { 
    this.issues$ = new Subject(); 
    this.issues$.subscribe(x => console.log('GOT IT', x)); 
    } 

    getList(): Observable<any> { 
    return this.issues$; 
    } 

    refresh() { 
    this.http.get('/whatever') 
     .map((response: Response) => response.json()) 
     .subscribe(data => this.issues$.next(data)); 
    } 
} 

ItemListComponent:

import { Component } from '@angular/core'; 
import { Observable } from 'rxjs'; 

import { ItemListDataService } from './item-list-data-service'; 
@Component({ 
    selector: 'app-item-list', 
    templateUrl: './item-list.component.html', 
    styleUrls: ['./item-list.component.css'], 
    providers: [ItemListDataService] 
}) 
export class ItemListComponent { 
    data: any; 

    constructor(itemListDataService: ItemListDataService) { 
    itemListDataService.getList().subscribe(data => { 
     console.log('DATA CHANGED'); 
     this.data = data; 
    }, err => { 
     console.log('ERR', err) 
    },() => { 
     console.log('DONE'); 
    }); 
    } 
} 

Der Teilnehmer in ItemListDataService.constructor erstellt wird jedes Mal aufgerufen, die refresh() genannt wird. Die einzige Sache, die nicht funktioniert, ist das Abonnement in der Komponente - keiner Rückruf wird dort jemals aufgerufen.

Was mache ich falsch?

+0

Woo Anrufe aktualisieren()? Woher erhält es den ItemListDataService? Sie haben ItemListDataService den Anbietern von ItemListComponent hinzugefügt, sodass die Komponente (und ihre Unterkomponenten) eine eigene Serviceinstanz erhält, die sich von den anderen Komponenten unterscheidet. –

+0

@JBNizet Danke, nach einigen Recherchen kam ich zum selben Schluss. Tatsächlich bestand das Problem darin, dass jede Komponente ihre eigene Instanz des Dienstes erhielt. Von Angular 1 (und zahlreichen anderen DI-Gerüsten) kommend erwartete ich, dass es sich um Singletons handelte. Lebe und lerne. :-) Fühlen Sie sich frei, das als Antwort zu posten. –

Antwort

9

Wie JB Nizet in einem Kommentar darauf hingewiesen hat, war der Grund, dass der Dienst kein Singleton war, d. H. Dass jeder Abonnent eine neue Instanz erhielt. Im Gegensatz zu Angular 1 sind in A2-Dienste keine Singletons.

Damit eine Instanz des Dienstes von mehreren Diensten/Komponenten gemeinsam genutzt werden kann, fügen Sie sie in die Provider der Eltern @Component oder @NgModule ein.

+0

Wie stelle ich sicher, dass der Dienst nicht mehr als einmal in der Root-Komponente instanziiert wird? Ich meine (mit ng2 in ionic) meine Komponenten hat kein Ereignis ngmodule. Ich nahm an, dass der Dienst, der in der Stammkomponente ngmodule definiert wurde, Singleton war, aber ich habe gerade bestätigt, dass sie Instanzen für jede Komponente haben. –

+0

Ich bin nicht wirklich mit ionischen vertraut, das Beste, was ich anbieten kann, googelt für "Ionic Service Singleton". Hier ist eines der besten Ergebnisse - könnte für Sie arbeiten: https://forum.ionicframework.com/t/how-to-create-a-ingleton-service/40113/2 –

Verwandte Themen