Angular NgRx 效果中的路由导航
Angular router navigation inside NgRx effect
Angular 路由器在 NgRx effect 中使用有任何限制吗?
我刚开始学习 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
操作,因此路由器行正在执行但导航不会发生。
@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:这个答案我没有验证,逻辑是这样的
应该有一种方法允许不为重定向创建单独的效果,比如
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
案例.
根据 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 }
);
Angular 路由器在 NgRx effect 中使用有任何限制吗?
我刚开始学习 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
操作,因此路由器行正在执行但导航不会发生。
@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:这个答案我没有验证,逻辑是这样的
应该有一种方法允许不为重定向创建单独的效果,比如
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
案例.
根据 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 }
);