私は更新しています @ ngrx/effects 1.xから2.xに
1.xでは、実際に状態ツリーへのアクセスがあります。
constructor(private updates$: StateUpdates<AppState>) {}
@Effect() bar$ = this.updates$
.whenAction(Actions.FOO)
.map(obj => obj.state.user.isCool)
.distinctUntilChanged()
.filter(x => x)
.map(() => ({ type: Actions.BAR }));
現在、2.xでは、アクションを実行するだけです。状態ツリーにアクセスする方法はまだありますか?または、これは良い習慣ではないので、このような使用は避けるべきですか?
constructor(private actions$: Actions) {}
@Effect() bar$ = this.actions$
.ofType(ActionTypes.FOO)
.map((obj: any) => {
console.log(obj); // here is action only
return obj.state.user.isCool // so it is wrong here
})
.distinctUntilChanged()
.filter(x => x)
.map(() => ({ type: ActionTypes.BAR }));
別の方法は.withLatestFrom(this.store)
を使用することです。したがって、完全なコードは次のとおりです。
constructor(
private actions$: Actions,
private store: Store<AppState>
) {}
@Effect() bar$ = this.actions$
.ofType(ActionTypes.FOO)
.withLatestFrom(this.store, (action, state) => state.user.isCool)
.distinctUntilChanged()
.filter(x => x)
.map(() => ({ type: ActionTypes.BAR }));
エフェクトはクラスプロパティである必要はありません。メソッドにすることもできます。つまり、コンストラクターに注入されたストアにアクセスできます。
この回答を書いている時点では、プロパティ宣言のセマンティクスとpublic
/private
コンストラクタのパラメータは明確ではありませんでした。プロパティが宣言されている場合コンストラクターの後に、それらはアクセスできますpublic
/private
コンストラクターパラメーターを介して宣言されたメンバー-したがって、関数としてエフェクトを宣言する必要はありません。
挿入されたストアでは、mergeMap
のような演算子を使用して状態を取得し、受け取った更新と組み合わせることができるはずです。
@Effect()
bar$(): Observable<Action> {
return this.actions$
.ofType(ActionTypes.FOO)
.mergeMap((update) => this.store.first().map((state) => ({ state, update })))
.map((both) => {
// Do whatever it is you need to do with both.update and both.state.
return both.update;
})
.distinctUntilChanged()
.filter(x => x)
.map(() => ({ type: ActionTypes.BAR }));
}
}
これが良い習慣であるかどうかは、意見の問題だと思います。状態の読み取り(理想的にはngrxスタイルのセレクターを作成すること)は妥当なように聞こえますが、特定の効果に必要なすべての情報が、それが聞いているアクションに含まれていれば、よりクリーンになります。