1つの効果で2つのアクションをダイパッチします。現在、これを達成するには2つの効果を宣言する必要があります。
// first effect
@Effect() action1$ = this.actions$
.ofType(CoreActionTypes.MY_ACTION)
.map(res => {
return { type: "ACTION_ONE"}
})
.catch(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}));
// second effect
@Effect() action2$ = this.actions$
.ofType(CoreActionTypes.MY_ACTION)
.map(res => {
return { type: "ACTION_TWO"}
})
.catch(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}));
1つのアクションを持ち、1つのエフェクトを介して2つのアクションのソースになることは可能ですか?
@Effect()
loadInitConfig$ = this.actions$
.ofType(layout.ActionTypes.LOAD_INIT_CONFIGURATION)
.map<Action, void>(toPayload)
.switchMap(() =>
this.settingsService
.loadInitConfiguration()
.mergeMap((data: any) => [
new layout.LoadInitConfigurationCompleteAction(data.settings),
new meetup.LoadInitGeolocationCompleteAction(data.geolocation)
])
.catch(error =>
Observable.of(
new layout.LoadInitConfigurationFailAction({
error
})
)
)
);
switchMap
とObservable.of
を使用できます。
@Effect({ dispatch: true }) action$ = this.actions$
.ofType(CoreActionTypes.MY_ACTION)
.switchMap(() => Observable.of(
// subscribers will be notified
{type: 'ACTION_ONE'} ,
// subscribers will be notified (again ...)
{type: 'ACTION_TWO'}
))
.catch(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}));
パフォーマンスの問題:
ディスパッチするたびにすべてのサブスクライバーをトリガーする多くのアクションをディスパッチする代わりに、 redux- batched-actions 。
これにより、これらの複数のアクションがすべてストアに適用された場合にのみ、サブスクライバーに警告できます。
例えば :
@Effect({ dispatch: true }) action$ = this.actions$
.ofType(CoreActionTypes.MY_ACTION)
// subscribers will be notified only once, no matter how many actions you have
// not between every action
.map(() => batchActions([
doThing(),
doOther()
]))
.catch(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}));
単純なアクションとObservablesのアクションを混在させる方法を誰もが疑問に思っている場合。
私は同じタスクで立ち往生しましたが、わずかな違いがありました。2つのアクションをディスパッチする必要があり、2番目のアクションはAPI呼び出しの後で、Observableになりました。何かのようなもの:
action1
は単なるアクションです:{type: 'ACTION_ONE'}
action2
は、アクションにマップされるAPI呼び出しです:Observable<{type: 'ACTION_TWO'}>
次のコードで問題が解決しました:
@Effect() action$ = this.actions$.pipe(
ofType(CoreActionTypes.MY_ACTION),
mergeMap(res =>
// in order to dispatch actions in provided order
concat(
of(action1),
action2
)
),
catchError(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}))
);
非同期の場合はmergeMap
を、同期の場合はconcatMap
を選択できます
@Effect() action$ = this.actions$
.ofType(CoreActionTypes.MY_ACTION)
.mergeMap(() => Observable.from([{type: "ACTION_ONE"} , {type: "ACTION_TWO"}]))
.catch(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}));
.do()およびstore.next()を使用することもできます
他の演算子に影響を与えずにオブザーバブルにコールバックを添付できるようにします/オブザーバブルを変更します
例えば.
@Effect() action1$ = this.actions$
.ofType(CoreActionTypes.MY_ACTION)
.do(myaction => this.store.next( {type: 'ACTION_ONE'} ))
.switchMap((myaction) => Observable.of(
{type: 'ACTION_TWO'}
))
.catch(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}));
(エフェクトクラスでストアへの参照が必要になります)