我正在迁移到使用 ngrx Effects,但遇到以下问题:由于 dispatch
返回 void
我不确定如何阻止路由器导航如果我的 ngrx 效果发生错误(例如,来自 this.userAccountService.updateFirstName(...
)。
来 self 的组件类:
updateFirstName() {
this.formStatus.submitted = true;
if (this.formStatus.form.valid) {
//Dispatch from the store
this.store.dispatch(new UpdateFirstNameAction(this.formStatus.form.value.firstName));
//Undesired behavior: will navigate even in case of error/failure!
this.router.navigate(['/dashboard/useraccount']);
}
}
来 self 的效果类:
@Effect()
updateFirstName$: Observable<Action> = this.actions$
.ofType(currentUserAccount.ActionTypes.UPDATE_FIRST_NAME)
.map((action: UpdateFirstNameAction) => action.payload)
.switchMap(firstName =>
this.userAccountService
.updateFirstName(firstName)
.map(() => new UpdateFirstNameSuccessAction(firstName))
//I obviously can't navigate from here
);
我不确定使用路由器从效果中导航是否是一个好的做法(甚至可能)。
有人可以建议一个干净的解决方案来防止路由器导航在我的影响下发生错误吗?
最佳答案
我建议使用@ngrx/router-store
模块。使用它,您可以创建路由操作,并且使用它,您有一些选择。
您可以从一个效果发出多个 Action 。因此,您的效果可以使用 concatMap
发出两个操作:成功操作和路由操作(使用 go
操作创建者创建):
import { go } from '@ngrx/router-store';
import 'rxjs/add/operator/concatMap';
@Effect()
updateFirstName$: Observable<Action> = this.actions$
.ofType(currentUserAccount.ActionTypes.UPDATE_FIRST_NAME)
.map((action: UpdateFirstNameAction) => action.payload)
.switchMap(firstName => this.userAccountService
.updateFirstName(firstName)
.concatMap(() => [
new UpdateFirstNameSuccessAction(firstName),
go(['/dashboard/useraccount'])
])
);
但是,您可能还需要考虑使用仅管理路由的单独效果:
import { go } from '@ngrx/router-store';
import 'rxjs/add/operator/mapTo';
@Effect()
updateFirstRouting$: Observable<Action> = this.actions$
.ofType(currentUserAccount.ActionTypes.UPDATE_FIRST_NAME_SUCCESS)
.mapTo(go(['/dashboard/useraccount']);
要考虑的另一件事是单个效果可以响应多个操作,因此您可以使用简单的操作类型到路由映射表来执行如下操作:
import { go } from '@ngrx/router-store';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
simpleRoutes: { [type: string]: string } = {
[currentUserAccount.ActionTypes.UPDATE_FIRST_NAME_SUCCESS]: '/dashboard/useraccount'
};
@Effect()
simpleRouting$: Observable<Action> = this.actions$
.map((action) => this.simpleRoutes[action.type])
.filter(Boolean)
.map((route) => go([route]));
无论您选择哪个选项,使用在效果内启动的路由操作进行导航都可以使事情更容易测试。编写效果测试很容易,以确保当效果接收到特定操作时,它会发出适当的操作。更多测试效果信息here .
关于redux - 在效果失败/错误的情况下防止路由器导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42189538/