История:
Привет всем.Я новичок в использовании библиотеки NgRx.В моем угловом проекте я использую защиту от маршрутизатора для предотвращения неаутентифицированного пользователя на неаутентифицированном веб-сайте.
Мой идеал - вызвать api rest rest для проверки содержимого токена локального хранилища.Если результат остальных API равен "success", за до возврата (true) выполните "store.dispatch (LoginSuccess)" , чтобы обновить информацию об авторизации входа в Store.
Проблема:
Когда выполняются действия по отправке.Действие «LoginSuccess» всегда выполняет бесконечный цикл, даже устанавливая {dispatch: false} в @ Effect () .После попробуйте и поиск по Google решение для этого.Эта проблема всегда в моем проекте.Надеюсь, что некоторые друзья по stackoverflow могут помочь мне. ~ Спасибо.
часть кодов:
auth.guard.ts
.....
....
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
const authData: {email: string, token: string} = JSON.parse(
String(localStorage.getItem('User')));
const authToken = authData && authData.token;
// loginServ is a REST API for verify token
return this.loginServ.VerifyToken(authToken).pipe(
concatMap((res: AuthResult) => {
if (res.result === 'success') {
this.store.dispatch(LoginSuccess({
isAuthenticated: true,
email: authData && authData.email,
token: authToken,
result: 'success',
message: 'success'
})); // <-- execute action infinite.
return of(true);
} else {
this.store.dispatch(LoginFailed({
isAuthenticated: false,
email: authData && authData.email,
token: authToken,
result: 'failed',
message: 'token illegal'
}));
localStorage.removeItem('User');
this.router.navigate(['']);
return of(false);
}
})
);
...
...
action.ts:
...
export const LoginSuccess = createAction(
'[auth] Login Success',
props<{
isAuthenticated: boolean,
email: string,
token: string,
result: string,
message: string,
}>()
);
....
...
reducer.ts
....
....
export const loginReducer = createReducer(
defaultState,
on(Login),
on(LoginSuccess, (state, userInfo) => {
console.log(state); // <-- for debug.
console.log(userInfo); // <-- for debug.
return {
...state,
...userInfo
};
}),
on(LoginFailed, (state, result) => {
return {
...state,
...result
};
}),
....
...
effect.ts
....
...
loginSuccess = createEffect(() => this.actions$
.pipe(
ofType(LoginSuccess),
map((user: any) => {
console.log(user);
const beStoreInfo = {
email: user.email,
token: user.token,
};
localStorage.setItem(
'User',
JSON.stringify(beStoreInfo));
return {
type: '[auth] Login Success',
isAuthenticated: true,
email: user.email,
token: user.token,
result: user.result,
message: user.message
};
}),
), {dispatch: false});
....
...
service_overview-routing.module.ts
....
// using lazy loading module
const routes: Routes = [
{
path: '',
canActivate: [AuthGuard],
component: ServiceOverviewComponent},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ServiceOverviewRoutingModule { }
....
app-routing.module.ts
Использование ленивого загрузочного модуля.
....
...
const routes: Routes = [
{ path: 'login', loadChildren: () => import('./login/login.module')
.then(m => m.LoginModule)},
{ path: 'register', loadChildren: () => import('./register/register.module')
.then(m => m.RegisterModule)},
{ path: 'service_overview', loadChildren: () => import('./service-overview/service-overview.module')
.then(m => m.ServiceOverviewModule)},
{ path: '', redirectTo: 'login', pathMatch: 'full' }
];
....
Среда:
УгловаяCli: 8.0.3
NgRx Store / Effect: 8.0.1
ОС: Ubuntu 18.04
.. Спасибо