NgRx 在登录成功操作时重定向到仪表板

And*_*uiz 2 redux angular ngrx-store

我正在学习 NgRx,我有一个基本问题。我一直在查看示例项目和其他答案,它们都是 2017 年的,架构有点不同。

我正在实现登录功能,到目前为止一切正常,正在调用操作,已发出其余 Api 请求等。我唯一的问题是:在哪里将用户重定向到仪表板?

行动:

export const loginAction = createAction(
    '[Login Page] User Login',
    props<{ login: string; password: string }>()
);

export const loginSuccessAction = createAction(
    '[Auth] Login Complete',
    props<{user: UserModel}>()
);

export const loginFailAction = createAction('[Auth] Login Fail', props<{error: any}>());
Run Code Online (Sandbox Code Playgroud)

减速机:

export interface AuthState{
    isLoggedIn: boolean;
    user: UserModel | null;
}
export const initialState: AuthState = {
    isLoggedIn: false,
    user: null
};

const _authReducer = createReducer(
    initialState,
    on(loginAction, (state) => ({...state, isLoggedIn: false, user: null})),
    on(loginSuccessAction, (state, {user}) => ({...state, isLoggedIn: true, user: user})),
    on(loginFailAction, (state) => ({ isLoggedIn: false, user: null }))
);

// tslint:disable-next-line:typedef
export function authReducer(state, action) {
    return _authReducer(state, action);
}
Run Code Online (Sandbox Code Playgroud)

效果:

@Injectable()
export class AuthEffects {
    constructor(
        private actions$: Actions,
        private authService: AuthService
    ) {}

    @Effect()
    login$ = createEffect(() =>
        this.actions$.pipe(
            ofType(loginAction),
            exhaustMap(action =>
                this.authService.login(action.login, action.password).pipe(
                    map(user => loginSuccessAction({user: user.redmine_user})),
                    catchError(error => of(loginFailAction({ error })))
                )
            )
        )
    );
}
Run Code Online (Sandbox Code Playgroud)

在我的组件中:

ngOnInit(): void
{
    this.loginForm = this._formBuilder.group({
        login   : ['', Validators.required],
        password: ['', Validators.required]
    });
}

onLogin(): void{
    this._store.dispatch(loginAction(this.loginForm.value));

}

ngOnDestroy(): void {

}
Run Code Online (Sandbox Code Playgroud)

正如我所说,操作已成功触发。我可以loginSuccessAction在 Redux Dev Tools 中看到正在调用。我见过有人在效果中进行重定向,但是这是正确的地方吗?如果没有,我应该去哪里做?有没有类似听行动的东西?

小智 6

如果我理解正确的话,您是在询问用户登录后在哪里执行重定向,但不是在技术意义上如何执行重定向,而是在架构意义上在哪里执行重定向是正确的位置。

让我们回顾一下您拥有的选项:

  1. 在效果中重定向- 这是您的第一个选项,在将成功操作分派到减速器之前或之后在效果中重定向。

  2. 从服务重定向- 您还可以在服务之后重定向,例如如下所示:

myService(): void {
 return this.http.get(url).pipe(
  tap(() => this.router.navigate([navigationURL]))
 )
}
Run Code Online (Sandbox Code Playgroud)

  1. 其他选项- 其他选项也是可能的,在您的问题中,您询问是否有一些东西允许监听操作,这几乎就是效果的用途,监听操作,但您也可以使用 监听 Observable 发射,并在以下情况下subscribe重定向发生这种情况时,我不推荐这种方法。

我认为添加subscriptions会给项目增加不必要的复杂性,因为subscriptions必须进行管理。

那么该怎么办?

老实说,这取决于你,这两种选择似乎都是有效的,我不会说这两种选择都是不好的做法。我个人更喜欢保持我的效果干净并在服务中进行。我觉得该服务更适合处理副作用,并且在测试时也使其更干净,但这是我个人的意见。

要记住的重要一点是,这两个选项都是有效的,并且不会增加不必要的复杂性。

还有一种小情况可能适用于您,如果您需要用户在store重定向之前处于重定向状态,那么最好在将操作分派给减速器之后将其放入效果中。如果您正在使用 Observables,那么无论哪种方式都可以,但如果它们具有紧密的关系,可能会更容易理解。