2016-08-22 17 views
13

私は自分自身の観測可能なサービスを作成しようとしていますが、サービスからの初期データを取得した後、サービスの更新はどのサブスクライバにも伝播しません。サービスは次のようになります。Angular2 Observable BehaviorSubjectサービスが動作しない

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; 
    } 
} 

サービスを使用するコンポーネントは、初期データを正しく取得します。そのコンポーネントはコンストラクタでデータを取得します。

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

これは、コンソールログに1つのGotchaを与えます。しかし、他の場所でsetKey(2,3)を使ってデータを更新した後、私は this.data.next(this.keys);を期待していました。 を使用してすべてのサブスクライバにデータを送信し、データはそれに応じてそのコンポーネント内で更新されます。しかし、データは、購読者に送信されません..

私はObservablesを考え出したと思ったが、私はここでポイントを欠場している場合は親愛なるではありませんしてください;)正しい方向の任意のポインタは非常に感謝されます!

+9

サービスを複数回提供しているため、異なるコンポーネントが異なるインスタンスになっているようです。 –

+1

モジュールで作業するときのアプローチは何でしょうか。私は似たようなサービスを持っています。私のコンポーネントの一部(別のモジュール)は、私の認証サービスで観測可能なものを購読し、変更されたときにデータを受信しますが、他のものはデータを受信しません。例えば。私のログイン(btn)コンポーネントがオブザーバで次回に発行されるとき、ログインコンポーネントは変更を認識しますが、ヘッダーとサイドバーコンポーネントは購読している間は怠惰な読み込みやキャッシュ、またはいくつかの親の子供の問題.. pff – webmaster

+1

@GünterZöchbauerこれはありがとう!私はコンポーネントの一部と親モジュールの両方でサービスを提供していました。それは私を夢中にさせていた! – jminuscula

答えて

8

値を発行するたびに、同じ変更されたオブジェクトを発行するのではなく、新しいオブジェクトを作成する必要があります。それは変化の検出の問題からあなたを守ります。新しいオブジェクトをthis.keysに変更するときは、常にそれを割り当てることをお勧めします。

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

あなたは

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

はまた ギュンターZöchbauerが言ったことを確認してくださいここ asObservable()を使用することができます。サービスをシングルトンとして提供していますか?

+0

は魅力的に機能します! (私のルーキーミスを修正した後、Gunterは*咳*咳*を指摘しました)。 – user3432565

21

私はある時点で同じ問題に直面しました。その理由は、サービスがシングルトンではなく、つまりすべての加入者が新しいインスタンスを取得するという理由が考えられます。 Angular 1と​​は対照的に、A2サービスではシングルトンではありません。

サービスの1つのインスタンスを複数のサービス/コンポーネントで共有したい場合は、の親@Componentまたは@NgModuleに入れます。

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

私はブートストラップでそれを持っていましたが、コンポーネント内部のプロバイダにもありました。それはすべての仕事:) tnxからそれを削除! しかし、私はRC.4であり、@NgModuleはありませんでした。あなたはおそらくRC.5を参照していますか?私がアップグレードしたとき、私は奇妙なtraceurメッセージをコンソールに持っていて、それはアプリケーションを壊してしまった(angular2サイトのアップグレードパスに従う)。アップグレードパスを試してもらったのですか? – user3432565

+0

私はRC5で始まったばかりなので、私はアップグレードパスとその癖にはあまり慣れていません。ラッキーな私、そう思う。:-) –

+0

文字通りすべての単一のソリューションを試してから約4時間が経過したが、これで最終的にすべての問題が解決されました。どうもありがとうございます –

関連する問題