2016-12-01 3 views
2

私は観測とngrxを使用して変更を保留中のシャドウコピーを持ってしようとしていると私は理解していない小さな問題に実行しているよ:ngrx:非同期パイプに使用するための観測を組み合わせる方法

export class SearchBoxContainerComponent { 
    filterSettings$: Observable<FilterSettings>; 
    filterChanges: {[key:string]: any}; 
    filterChanges$: Subject<{[key:string]: any}>; 
    constructor(private store: Store<fromRoot.State>) { 
     this.filterChanges = {}; 
     this.filterChanges$ = new Subject(); 
     this.filterSettings$ = Observable.combineLatest(
      store.let(fromRoot.getFilterSettings), 
      this.filterChanges$, 
      (filterSettings, filterChanges) => { 
       return Object.assign({}, filterSettings, filterChanges); 
      } 
     ); 
     this.filterChanges$.subscribe(foo => { 
      console.log('filterChanges$: ', foo); 
     }); 
     this.filterSettings$.subscribe(foo => { 
      console.log('filterSettings$: ', foo); 
     }); 
     this.filterChanges$.next(this.filterChanges); 
    } 

    updateSetting(key, value) { 
     this.filterChanges = Object.assign({}, this.filterChanges, {[key]: value}); 
     this.filterChanges$.next(this.filterChanges); 
    } 

    submitSearchbox() { 
     // TODO send ngrx action to really update the filterSettings 
    } 
} 

ここで私が代わりに直接ngrxストアから、観察を取得するために

this.filterSettings$ = store.let(fromRoot.getFilterSettings); 

を使用してのObservable.combineLatest使用しています。

私の問題は、自分の検索ボックスが開いたときに、最初はすべてがヌルであるということです。値を更新した後でさえ、すべてが設定されます。 store.letと直接バインドすると動作します。

私はこの

<my-component [filterSettings]="filterSettings$ | async"></my-component> 

ように私のHTMLに非同期パイプを使用しますが、検索ボックスが開いた後にのみ評価を受けるように、それは* ngIfです。 私は、非同期パイプがすべてのアクションが起こった後にサブスクライブし、新しいイベントがなくても値を取得しないと推測します。しかし、なぜstore.letで動作しますか?それは常にあなたに価値を与える別の観測可能性ですか?

質問私は間違っていると思いますが、私はまだ何かが欠けているという印象を受けます...ボーナスの質問:これはデータのシャドウコピーを持ち、

+0

サブスクライバからの最新の値を保持するためだけに、別の変数 'this.filterChanges'を保持しません。より良い方法で 'updateSetting'を実装する演算子があります。私はこれをCode Reviewに提出することをお勧めします。 –

+0

私は、他の場所でシャドウコピーにアクセスする必要があるので、私が思うより良いフィット感が得られるngrxレデューサーでこのすべてのロジックを動かしたと考えました...しかし、この観察可能なものすべてについて良いレッスンでした。 – arturh

+0

それは良い方法です –

答えて

4

rxjs/Subjectの代わりにrxjs/BehaviorSubjectを使用してください。受信した最後のアイテムを新しい加入者に供給します。

this.filterChanges = {}; 
this.filterChanges$ = new BehaviorSubject(this.filterChanges); 

それは、コンストラクタに値を取るので、あなたは、後にnext()する必要はありません。 Observable.combineLatest()はそれまでに期待どおりに動作するはずです。

+0

あまりにもうまくいきました、ありがとう – arturh

関連する問題