Mam AuthGuard (używany do routingu), który implementuje CanActivate .
canActivate() {
return this.loginService.isLoggedIn();
}
Mój problem polega na tym, że wynik CanActivate zależy od wyniku http-get - usługa logowania zwraca Observable .
isLoggedIn():Observable<boolean> {
return this.http.get(ApiResources.LOGON).map(response => response.ok);
}
Jak mogę to połączyć - sprawić, by CanActivate zależało od stanu zaplecza?
# # # # # #
EDYCJA: Proszę zwrócić uwagę, że to pytanie pochodzi z 2016 roku - zastosowano bardzo wczesną fazę kątownika / routera.
# # # # # #
angular
angular2-routing
angular2-http
Philipp
źródło
źródło
canActivate()
może zwrócićObservable
, po prostu upewnij się, żeObservable
zakończyło się (tj.observer.complete()
).take(1)
operatora Rx, aby osiągnąć kompletność strumienia, a co jeśli zapomnę go dodać?Odpowiedzi:
Należy zaktualizować „@ angular / router” do najnowszej. np. „3.0.0-alfa.8”
zmodyfikować AuthGuard.ts
Jeśli masz jakieś pytania, zapytaj mnie!
źródło
isLoggedIn()
toPromise
można zrobićisLoggedIn().then((e) => { if (e) { return true; } }).catch(() => { return false; });
Mam nadzieję, że to pomoże przyszłych turystów!import 'rxjs/add/observable/of';
Aktualizacja odpowiedzi Kery Hu na Angular 5+ i RxJS 5.5, gdzie
catch
operator jest przestarzały. Należy teraz używać operatora catchError w połączeniu z operatorami potoku i 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); }) ); } }
źródło
canActivate () akceptuje
Observable<boolean>
jako zwróconą wartość. Strażnik będzie czekał, aż Obserwowalny rozwiąże i spojrzy na wartość. Jeśli `` prawda '' przejdzie kontrolę, w przeciwnym razie (wszelkie inne dane lub wyrzucony błąd) odrzuci trasę.Można użyć
.map
operatora do przekształceniaObservable<Response>
sięObservable<boolean>
w taki sposób:źródło
Zrobiłem to w ten sposób:
Jak widać, wysyłam funkcję rezerwową do userService.auth, co zrobić, jeśli wywołanie http nie powiedzie się.
A w userService mam:
źródło
To może ci pomóc
źródło
CanActivate działa z Observable, ale kończy się niepowodzeniem, gdy wykonywane są 2 wywołania, takie jak CanActivate: [Guard1, Guard2].
Tutaj, jeśli zwrócisz Observable lub false z Guard1, wtedy również sprawdzi Guard2 i zezwoli na dostęp do trasy, jeśli Guard2 zwróci true. Aby tego uniknąć, Guard1 powinien zwrócić wartość logiczną zamiast Observable of boolean.
źródło
w canActivate () możesz zwrócić lokalną właściwość boolowską (w twoim przypadku domyślnie jest to false).
Następnie w wyniku usługi LoginService możesz zmodyfikować wartość tej właściwości.
źródło