我正在迁移以使用 ngrx效果而且我遇到以下问题:因为dispatch
返回void
我不确定如果我的错误发生,如何阻止路由器导航ngrx效应(例如来自this.userAccountService.updateFirstName(...
)。
来自我的组件类:
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']);
}
}
从我的效果课:
@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
);
我不确定使用路由器以便从效果中导航是一种很好的做法(甚至可能)。
有人可以建议一个干净的解决方案,以防止路由器导航,以防我的效果发生错误吗?
答案 0 :(得分:1)
我建议使用@ngrx/router-store
模块。有了它,您可以创建路由操作,并使用它,您有几个选项。
您可以从单个效果中发出多个动作。因此,您的效果可以使用const
发出两个操作:您的成功操作和路由操作(使用go
操作创建者创建):
concatMap
但是,您可能还需要考虑使用仅管理路由的单独效果:
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']);
无论您选择哪个选项,使用在效果中启动的导航的路由操作都可以使事情更容易测试。编写效果测试很容易,以确保当效果收到特定操作时,它会发出适当的操作。有关测试效果的更多信息here。
答案 1 :(得分:0)
你可以采用以下两种方式之一。
使用效果,捕捉SUCCESS操作,然后重定向:
@Effect() someeffect$: Observable<Action> = this.actions$
.ofType(currentUserAccount.ActionTypes.UPDATE_FIRST_NAME_SUCCESS)
.do(action => /* do redirect (action.payload) */);
订阅:
让我们说这是你的状态:
{
account: {
username: null
}
}
组件:
var username$ = this.store.select(account => account.username);
username$.subscribe(user => {
// the user have changed due to reducer who is getting the action with new user.
// do here redirect...
});