web-dev-qa-db-ja.com

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

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

私はオブザーバブルを理解したと思ったが、ここにポイントが欠けている場合は友好的になってはいけない;)正しい方向のポインタは大歓迎です!

17
kjoetools

値を発行するたびに、同じ変異オブジェクトを発行するのではなく、新しいオブジェクトを作成する必要があります。これにより、変更検出の問題から保護されます。ただし、変更するときは常に_this.keys_に新しいオブジェクトを割り当てる方が良いでしょう。

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

ここでasObservable()を使用できます

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

GünterZöchbauerが言ったことも確認してください。シングルトンとしてサービスを提供していますか?

9
j2L4e

ある時点で同じ問題に直面しました。その理由は、サービスがシングルトンではないこと、つまりすべてのサブスクライバーが新しいインスタンスを取得していることです。 Angular 1に反して、A2サービスではシングルトンではありません。

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

@NgModule({
  declarations: [],
  imports: [],
  bootstrap: [AppComponent],
  providers: [DataService]
})
export class AppModule {
}
35
Konrad Garus