2016-08-22 29 views
13

Próbuję utworzyć własną usługę obserwowalną, ale po otrzymaniu początkowych danych z usługi wszelkie aktualizacje usługi nie są propagowane do żadnych subskrybentów. Usługa wygląda następująco:Usługa Angular2 Observable BehaviorSubject nie działa

import { Injectable } from '@angular/core'; 
import { Observable, BehaviorSubject } from 'rxjs/Rx'; 

@Injectable() 
export class DataService { 
    keys : number[] = [4,5,1,3,2]; 
    private data :BehaviorSubject<number[]> = new BehaviorSubject(this.keys); 

    constructor() {}; 

    public setKey(i:number, val:number) :void { 
    this.keys[i]=val; 
    this.data.next(this.keys); 
    } 
    public getData() :Observable<number[]> { 
    return new Observable(fn => this.data.subscribe(fn)); 
    } 
    public getKeys() :number[] { 
    return this.keys; 
    } 
} 

składnik korzystający z usługi dostaje dane początkowe dobrze. ten komponent pobiera swoje dane w konstruktorze:

constructor(public dataService: DataService) { 
    dataService.getData().subscribe(data => { 
     console.log("Gotcha!"); 
     this.data.datasets[0].data = data) 
    }); 
}; 

co daje jeden komunikat Gotcha w logu konsoli. Ale po aktualizacji danych z setKey (2,3) gdzie indziej, oczekiwałem, że this.data.next (this.keys); wysyłanie danych do wszystkich subskrybentów, a dane będą aktualizowane odpowiednio w tym komponencie. ale żadne dane nie są wysyłane do subskrybentów.

Myślałem, że wymyśliłem obserwowalne, ale proszę nie bądź przyjazny, jeśli brakuje mi tu punktu;) wszelkie wskazówki we właściwym kierunku będą bardzo mile widziane!

+9

Wygląda na to, że usługa jest świadczona więcej niż jeden raz, co prowadzi do różnych składników, w których występują różne wystąpienia. –

+1

Jakie powinno być podejście do pracy w modułach. Mam podobną usługę. Niektóre z moich komponentów (w różnych modułach) subskrybują się w obserwowalnej usłudze uwierzytelniania i odbierają dane po zmianie, ale inne nie otrzymują danych. Na przykład. kiedy mój komponent logowania (btn) emituje następny element na obserwatorze, komponenty logowania widzą zmianę, ale moje komponenty nagłówka i paska bocznego nie są, gdy są one również subskrybowane, myślę, że ma to związek z leniwym ładowaniem lub z pamięcią podręczną lub niektórymi rodzic dziecko problem .. pff – webmaster

+1

@ GünterZöchbauer dzięki za to! Dostarczałem tę usługę zarówno w ramach komponentu, jak i modułu nadrzędnego. To doprowadzało mnie do szaleństwa! – jminuscula

Odpowiedz

8

Za każdym razem, gdy emitujesz wartość, powinieneś utworzyć nowy obiekt zamiast emitować ten sam zmutowany obiekt. To ochroni Cię przed problemami z wykrywaniem zmian. Lepiej jest zawsze przypisać nowy obiekt do this.keys, kiedy go zmienisz.

this.data.next([...this.keys]); 

Można użyć asObservable() tutaj

public getData(): Observable<number[]> { 
    return this.data.asObservable(); 
} 

Należy również sprawdzić, co Günter Zöchbauer powiedział. Czy świadczysz usługę jako singleton?

+0

który działa jak urok! (po tym, jak poprawiłem swój debiutancki błąd, który Gunter wskazał * kaszel * kaszel *) .. – user3432565

21

W pewnym momencie stanąłem wobec tego samego problemu. Prawdopodobnie przyczyną jest to, że twoja usługa nie jest pojedynczą, tzn. Że każdy subskrybent otrzymuje nową instancję. W przeciwieństwie do Angular 1, usługi A2 nie są pojedynczymi.

Jeśli chcesz mieć jedną instancję usługi współużytkowaną przez wiele usług/komponentów, umieść ją w providers swojego rodzica @Component lub @NgModule.

@NgModule({ 
    declarations: [], 
    imports: [], 
    bootstrap: [AppComponent], 
    providers: [DataService] 
}) 
export class AppModule { 
} 
+1

Miałem go w bootstrapie, ale także w dostawcach wewnątrz komponentów. usunięcie go z tego wszystkiego działało :) tnx! zastanawiasz się jednak, byłem na RC.4 i nie miałem @NgModule. Masz na myśli prawdopodobnie RC.5? kiedy uaktualniłem otrzymałem różnego rodzaju dziwne komunikaty traceur w konsoli i zepsuło to moją aplikację (po ścieżce uaktualnienia witryny kątowej2). czy wypróbowałeś ich ścieżkę aktualizacji i udało Ci się uciec? – user3432565

+0

Zacząłem tylko od RC5, więc nie znam się dobrze na ścieżce aktualizacji i jej dziwactwach. Na szczęście, jak sądzę.:-) –

+0

Po prawie 4 godzinach próbowania dosłownie każdego rozwiązania, to w końcu rozwiązało wszystkie moje problemy. Dziękuję bardzo –