4

Vor jeder Anfrage möchte ich sicher sein, dass ein Benutzerprofil verfügbar ist. Ich benutze einen canActivateChild-Wächter, um dies zu tun.angular2 guard funktioniert nicht auf Seitenaktualisierung

Gemäß der Dokumentation von angular2 ist es möglich, eine beobachtbare zurückzukehren: https://angular.io/api/router/CanActivateChild

app.routes.ts

export const routes: Routes = [ 
    { 
    path: '', 
    canActivateChild: [ProfileGuard], 
    children: [ 
     { 
     path: 'home', 
     component: HomeComponent, 
     canActivate: [AuthGuard] 
     }, 
     { 
     path: 'login', 
     component: LoginComponent, 
     canActivate: [GuestGuard] 
     }, 
} 
]; 

Die canActivatedChild wird, bevor das Kind Route ausgeführt canActivate

Profil. guard.ts:

export class ProfileGuard implements CanActivateChild { 

    constructor(private profileService: ProfileService, private snackbar: MdSnackBar) { } 

    canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> { 

    if (this.profileService.user == null && localStorage.getItem('__token') != null) { 
     return this.profileService.loadProfile().map((user) => { 
     console.log('profile loaded'); 
     this.profileService.user = <UserModel>user.data; 
     return true; 
     }); 
    } 
    return true; 
    } 

} 

Lastprofilfunktion:

public loadProfile(): Observable<any> { 
    console.log('load'); 
    return this.http.get('/profile').map(res => res.json()); 
    } 

Wenn ich durch das Menü navigieren (<a> mit routeLink) den console.log('profile loaded') funktioniert. Aber wenn ich die Seite mit f5 oder durch den Browser neu lade, kommt es nie dorthin.

Die console.log('load') wird immer ausgeführt.

EDIT:

Wenn ich in canActivateChild Rückkehr:

return Observable.of(true).map(() => { 
    console.log('Test'); 
    return true; 
}); 

Es funktioniert gut ... Ich habe das console.log('test')

+0

In der F12-Browserkonsole auf der Registerkarte Netzwerk sehen Sie die Anforderung an/profile und ist es erfolgreich? –

+0

Dies ist ein interessantes Problem. Funktionieren die Dinge wie erwartet, wenn Sie nur 'Observable.of (true)' zurückgeben, anstatt 'this.profileService.loadProfile()' aufzurufen? – BeetleJuice

+0

Können Sie versuchen, ein PLNKR wenn möglich, so erhalten Sie Hilfe sehr schnell. Sie können Dummy-Daten für HTTP-Aufrufe verwenden – Skeptor

Antwort

0

Ich lief auf einem RC von @angular/router. Nachdem ich das aktualisiert hatte, funktionierte es wie erwartet.

1

Ich denke, es zu lösen ist, bevor Sie eine Antwort erhalten, versuchen Sie Hinzufügen eines Replay-Betreffs, der nach der Rückgabe der Anfrage zu "True" oder "False" führt

import {Observable, ReplaySubject} from 'rxjs/Rx'; 

public loadProfile(): Observable<any> { 
    console.log('loading profile'); 
    return this.http.get('/profile').map(res => res.json()); 
} 

public isUserLoggedInObs(): Observable<boolean> { 
    const userLoggedIn: ReplaySubject<boolean> = new ReplaySubject<boolean>; 
    this.loadProfile.first().subscribe(
    user => userLoggedIn.next(user.loggedIn === true) 
) 
    return userLoggedIn.asObservable(); 
} 


canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> { 
    return this.profileService.isUserLoggedInObs() 
} 
Verwandte Themen