Есть ли у маршрутизатора 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.info(data);
this.router.navigateByUrl('/');
return new authenticationActions.AuthenticateSuccessAction(user);
})
.catch(error => { console.info(error); return Observable.throw(error); })
);
Консоль регистрирует переменную данных и запускается действие AuthenticateSuccessAction, поэтому линия маршрутизатора выполняется, но навигации не происходит.
Я уже пробовал разные URL-адреса, а также отключил всех охранников и создал кнопку тестирования на странице входа, чтобы использовать тот же оператор, и он перемещается. Проблема в том, что утверждение внутри эффекта. Это очень очень странно
У меня такая же реализация, как и у вас, и я могу без проблем перенаправить свое приложение. Это глупо, но убедитесь, что вы ввели маршрутизатор в свой конструктор.
осуществлять навигацию внутри оператора tap (в старых версиях rxjs он назывался do).





@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.info(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(['/']))
);
Используйте выхлопную карту, и когда вы отправляете действие AuthenticateSuccessAction, сделайте другой эффект для перенаправления.
Лично мне нравится отделять все сервисы от эффектов, тогда вы можете использовать оператор catchError () после успешного входа в систему для отправки другого действия в случае неудачного входа в систему.
надеюсь, что это сработает. PS: Я не проверял этот ответ, но логика такая.
эта отправка: false - это ключ ;-)
@ Стюарт Аллен, дружище! Мне было интересно, почему эффект продолжает зацикливаться
Интересно видеть, как вы отправляете одно действие, которое передается как редуктору, так и следующему обработчику эффекта. Я посмотрю, сработает ли это, но я надеюсь, что это так.
Должен быть подход, позволяющий не создавать отдельный эффект для редиректа, что-то вроде
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 в случае сбоя.
Это должно работать нормально, возможно, попробуйте другой URL-адрес, чтобы убедиться, что это не ошибка, прежде чем вы перейдете к корневому каталогу?
this.router.navigateByUrl('/login'); Убедитесь, что вы не используете что-то вроде AuthGuard, которое перенаправляет вас обратно на экран входа в систему.