我想在一个效果中发送两个动作。 目前我必须声明两种效果来实现这一目标:
// 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
}));
是否可以通过单一效果成为一个动作的源头?
答案 0 :(得分:35)
@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
})
)
)
);
答案 1 :(得分:9)
您可以使用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
}));
答案 2 :(得分:4)
您可以为异步选择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
}));
答案 3 :(得分:2)
你也可以使用.do()和store.next()
do允许您将回调附加到observable而不影响其他运算符/更改observable
e.g。
@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
}));
(您需要在效果类中引用商店)
答案 4 :(得分:1)
如果有人想知道如何将简单动作与Observables中的动作混合使用。
我被困在相同的任务上,但差别很小:我需要分派两个动作,第二个动作在API调用之后进行,这使其成为可观察的。像这样:
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
}))
);
答案 5 :(得分:1)
如何在flatMap
和8.3.0
的ngrx effects
版本语法中使用以下actions
:
someEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(CoreActionTypes.MY_ACTION),
flatMap((data) => [
CoreActionTypes.MY_ACTION_2(data),
CoreActionTypes.MY_ACTION_3(data),
])
)
);