2017-05-11 3 views
3

Ich habe ein "CanActivate" auf meinem Web-Service überprüft, ob der Benutzer angemeldet istAngular 2 - CanActivate beobachtbare get Wert Abonnieren nach

Die "CanActivate" Rückkehr Observable.. Die einzige Sorge ist, dass ich den Wert dieser boolean, um sich erholen würde müssen in der Lage sein, meine Ansicht anzupassen, wenn der Benutzer verbunden ist oder nicht, ohne eine zweite Anfrage redoing ...

canActivate(): Observable<boolean>|boolean { 
    return this.connected(); 
    } 
public connected() : Observable<boolean>{ 
    return this.http.get(this.connectedUrl,{ withCredentials: true }) 
     .map(this.extractBoolean) 
     .catch(this.handleError); 
    } 

Danke für Ihr Hilfe

+0

Alles, was Sie in der Benutzerseite speichern vom Benutzer bearbeitet werden. Also sollten Sie in jeder Seitenansicht eine neue Anfrage senden. – mohammad

+0

Was ist die Frage? –

+0

@DanielCooke Wenn ich mich nicht irre, hat Jordan einen Wächter, in dem er einen Ajax-Anruf tätigt, um einen Benutzer zu bekommen. Danach wird eine Komponente geladen und in der Komponente führt er einen zweiten Ajax-Aufruf durch, um einen Benutzer zu erhalten. Frage: Wie mache ich das mit nur einem Anruf? –

Antwort

1

ich hatte ein ähnliches Problem und löste es einen Authentifizierungs-Service, wo ich stattdessen ein BehaviorSubject verwendet, um das Element Authentifizierungsstatus zu verfolgen:

public member: Subject<Member> = new Subject<Member>(); 

private _cachedMember: Member; 
private _member$: BehaviorSubject<Member>; 

constructor(private _http: Http, private _router: Router) {   
} 

get member$(): Observable<Member> {  
    if (!this._cachedMember) {   
     this.getAuthorizedMember().subscribe(); 
    } 
    return this._member$.asObservable(); 
} 

private getAuthorizedMember(): Observable<Member> { 
    // call your auth API and set _cachedMember accordingly: 
    this._cachedMember = member; 
    this._member$.next(this._cachedMember); 
} 

Meine auth.guard.ts canActivate Umsetzung:

Die Else-Anweisung speichert die URL-Anforderung, sodass das Mitglied nach der Anmeldung korrekt umgeleitet wird.

Dann müssen Sie nur Ihre Authentifizierungs-API aufrufen, wenn _cachedMember null ist. Denken Sie daran, _cachedMember beim Abmelden auf null zu setzen und die Betreffenden zu informieren.

logout() { 
    this._cachedMember = null; 
    this._member$.next(this._cachedMember); 
} 

[EDIT] fand ich ein Problem mit der früheren Lösung. Es ist eine gute Idee, den Autorisierungsmechanismus in eine Observable zu verpacken und eine Nullprüfung durchzuführen, wenn der Betreff _member $ zugewiesen ist. Dann ist der Anfangszustand gültig, wenn direkt zu einer überwachten Route navigiert wird!

1

Wenn Sie einige Daten speichern möchten, wenn Sie eine Anforderung in Ihrem Back-End stellen, um sicherzustellen, dass ein Benutzer verbunden ist, erstellen Sie anstelle der HTTP-Anforderung in eine service, die diese Anforderung ausführt (was eine gute Vorgehensweise ist) sowieso und das solltest du tun, ob du eine Anfrage speichern willst oder nicht.

Das heißt, in Ihrem service, die ein Singleton ist, können Sie einfach map Ihren Anruf (die in ein Observable führt) und den Wert in Ihrem service speichern.

Zum Beispiel:

@Injectable() 
export class SomeService { 
    private userData: IUserData; 

    constructor(private http: Http) { } 

    getUserDataIfConnected() { 
    this.http.get('http://some-url') 
     .map((res: Response) => res.json() as IUserData) 
     .map(userData => this.userData = userData) 
    } 
} 

Dann in dem Hut:

canActivate(): Observable<boolean> { 
    return this.someService.getUserDataIfConnected() 
    // if there was no error, we don't care about the result, just return true : The user is connected 
    .mapTo(true) 
    // if the user wasn't logged, your backend shoud return an HTTP error code in the header 
    // and angular HTTP service will throw an error 
    .catch(err => return Observable.of(false)) 
} 

Es ist nicht komplizierter zu sein als die :)