Angular路由器在NgRx效果中是否有任何限制?
我刚刚开始学习NgRx,我有以下代码:
@Effect() public authenticate$ = this.actions$
.ofType(authenticationActions.AUTHENTICATE)
.switchMap((action: AuthenticateAction) => this.authenticationService.authenticate(action.payload)
.map((data: TokenData) => {
const user: User = {
token: data.token,
username: 'dummy',
};
console.log(data);
this.router.navigateByUrl('/');
return new authenticationActions.AuthenticateSuccessAction(user);
})
.catch(error => { console.log(error); return Observable.throw(error); })
);
控制台记录数据变量并且正在触发AuthenticateSuccessAction
操作,因此正在执行路由器行,但导航不会发生。
答案 0 :(得分:12)
@Effect() public authenticate$ = this.actions$.pipe(
ofType(authenticationActions.AUTHENTICATE),
map(action => action.payload),
exhaustMap((auth: any) =>
this.authenticationService.authenticate(auth)
.map((data: TokenData) => {
return user: User = {
token: data.token,
username: 'dummy',
};
}).catch(error => { console.log(error); return Observable.throw(error);
}).pipe(
map(user =>new authenticationActions.AuthenticateSuccessAction(user))
)
);)
@Effect({ dispatch: false })
loginSuccess$ = this.actions$.pipe(
ofType(authenticationActions.AuthenticateSuccessAction),
tap(() => this.router.navigate(['/']))
);
使用exhaustMap并在发送' AuthenticateSuccessAction'动作,为重定向做另一个效果。
就个人而言,我喜欢将所有服务与效果分开,然后您可以在成功登录后使用catchError()运算符,以便在登录失败时调度其他操作。
希望这有效。 PS:我没有验证这个答案,但逻辑是这样的。答案 1 :(得分:2)
应该有一种方法,允许不为重定向创建单独的效果,例如
this.actions$.pipe(
ofType(authenticationActions.AUTHENTICATE),
switchMap(action =>
this.authenticationService.authenticate(action.payload).pipe(
map(data => new authenticationActions.successAction(data)),
tap(() => this.router.navigate(['/'])),
catchError(error => new authenticationActions.failAction(error))
)
);
问题在于,如果服务调用失败,将不会调用tap
,如果失败,则map
和tap
都将被跳过,而以catchError
受益。
答案 2 :(得分:0)
按照 m.akbari 的回应,如果他们使用不同的动作,“dispatch : false”转到最后。
关键是“dispatch : false”,如果没有指明会产生无限循环
loginNavigate$ = createEffect(
() => this.actions$.pipe(
ofType(usuariosActions.loginUsuarioSuccess),
tap(() => {
console.log('iniciando la navegacion');
this.router.navigate(['/']);
})
), { dispatch: false }
);