У меня есть AuthGuard (используется для маршрутизации), который реализует CanActivate .
canActivate() {
return this.loginService.isLoggedIn();
}
Моя проблема в том, что CanActivate-result зависит от http-get-result - LoginService возвращает Observable .
isLoggedIn():Observable<boolean> {
return this.http.get(ApiResources.LOGON).map(response => response.ok);
}
Как я могу объединить их - сделать CanActivate зависимым от состояния серверной части?
# # # # # #
РЕДАКТИРОВАТЬ: Обратите внимание, что этот вопрос с 2016 года - использовалась очень ранняя стадия angular / router.
canActivate()
может вернутьObservable
, просто убедитесь, чтоObservable
он завершился (т.е.observer.complete()
).take(1)
оператора Rx для достижения полноты потока. Что, если я забуду его добавить?Ответы:
Вам следует обновить "@ angular / router" до последней версии. например, "3.0.0-alpha.8"
изменить AuthGuard.ts
Если есть вопросы, задавайте!
источник
isLoggedIn()
этоPromise
, вы можете сделать ,isLoggedIn().then((e) => { if (e) { return true; } }).catch(() => { return false; });
надеюсь , это поможет будущим путешественникам!import 'rxjs/add/observable/of';
Обновление ответа Кери Ху для Angular 5 и RxJS 5.5, где
catch
оператор устарел. Теперь вы должны использовать оператор catchError вместе с операторами pipe и lettable .import { Injectable } from '@angular/core'; import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs/Observable'; import { catchError, map} from 'rxjs/operators'; import { of } from 'rxjs/observable/of'; @Injectable() export class AuthGuard implements CanActivate { constructor(private loginService: LoginService, private router: Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { return this.loginService.isLoggedIn().pipe( map(e => { if (e) { return true; } else { ... } }), catchError((err) => { this.router.navigate(['/login']); return of(false); }) ); } }
источник
canActivate () принимает
Observable<boolean>
как возвращаемое значение. Охранник будет ждать разрешения наблюдаемого и смотреть на значение. Если «истина», он пройдет проверку, иначе (любые другие данные или выданная ошибка) отклонит маршрут.Вы можете использовать
.map
оператор, чтобы преобразоватьObservable<Response>
егоObservable<boolean>
так:источник
Я сделал это так:
Как видите, я отправляю в userService.auth резервную функцию, что делать, если http-вызов не работает.
А в userService у меня есть:
источник
Это может вам помочь
источник
CanActivate действительно работает с Observable, но не работает, когда выполняются 2 вызова, такие как CanActivate: [Guard1, Guard2].
Здесь, если вы вернете Observable false от Guard1, тогда он также проверит Guard2 и разрешит доступ к маршруту, если Guard2 вернет true. Чтобы этого избежать, Guard1 должен возвращать логическое значение вместо Observable of boolean.
источник
в canActivate () вы можете вернуть локальное логическое свойство (в вашем случае по умолчанию false).
А затем в результате LoginService вы можете изменить значение этого свойства.
источник