我使用Angular2和ngrx/store和ngrx/effects进行状态管理。
当某个操作失败时,我想显示一条错误消息,但似乎我无法在@Effects()
块中执行此任务。
@Effect() selectOfficeFail$ = this.actions$
.ofType(SelectOfficeActions.LOAD_FAIL)
.do(() => {
alert('Error! No offices found!'); // I keep entering here
});
当上面的代码运行时,警报将无限次运行,直到浏览器崩溃。似乎@Effect()
必须返回一个新的dispatch()
,但我不明白为什么。为什么上面的alert()运行了无数次?
编辑:我是不是调度SelectOfficeActions.LOAD_FAIL
多次。只有一次
[UPDATE]现在最好的方法是使用dispatch
选项,像这样:
@Effect({dispatch: false}) selectOfficeFail$ = this.actions$
.ofType(SelectOfficeActions.LOAD_FAIL)
.do(() => {
alert('Error! No offices found!'); // I keep entering here
});
它的意思是"响应这个动作,但不发送另一个"。
问题是do
允许动作通过您的效果,然后由商店再次调度动作。您可以使用filter
来防止这种情况发生:
@Effect() selectOfficeFail$ = this.actions$
.ofType(SelectOfficeActions.LOAD_FAIL)
.do(() => {
alert('Error! No offices found!'); // I keep entering here
})
.filter(() => false);
如果使用createEffect
函数,则dispatch: false
标志需要作为配置参数(ngrx)传递。io引用)
effectName$ = createEffect(
() => this.actions$.pipe(
ofType(FeatureActions.actionOne),
tap(() => console.log('Action One Dispatched'))
),
{ dispatch: false }
// FeatureActions.actionOne is not dispatched
);
是的,你是对的@effect
需要调度一个新的动作,但我认为你的应用程序逻辑有问题。
您不应该在组件或服务中调度SelectOfficeActions.LOAD_FAIL
操作,而是调用@Effect
的LOAD操作,然后根据标准依次调度LOAD_COMPLETE
或LOAD_FAIL
。
类似于库github
中的示例 @Effect() login$ = this.updates$
// Listen for the 'LOGIN' action
.whenAction('LOGIN')
// Map the payload into JSON to use as the request body
.map(update => JSON.stringify(update.action.payload))
.switchMap(payload => this.http.post('/auth', payload)
// If successful, dispatch success action with result
.map(res => ({ type: 'LOGIN_SUCCESS', payload: res.json() }))
// If request fails, dispatch failed action
.catch(() => Observable.of({ type: 'LOGIN_FAILED' }));
);