Angular2 – Extending router e Observable

In angular2 rc2 con il modulo router v 3.0.0.6alpha, estendo il RouterOulet per verificare se l’utente è loggato prima di accedere all’admin. Quindi questo è il codice:

@Directive({ selector: 'router-outlet' }) export class LoggedInRouterOutlet extends RouterOutlet { publicRoutes: Array; private parentOutletMap: RouterOutletMap; private userService: UserService; private parentRouter: Router; constructor( parentOutletMap: RouterOutletMap, _location: ViewContainerRef, @Attribute('name') name: string, userService: UserService, parentRouter: Router ) { super(parentOutletMap, _location, name); this.parentRouter = parentRouter; this.parentOutletMap = parentOutletMap; this.userService = userService; this.publicRoutes = [ 'public', 'login' ]; } activate(factory: ComponentFactory, activatedRoute: ActivatedRoute, providers: ResolvedReflectiveProvider[], outletMap: RouterOutletMap) { if (this._canActivate(factory.selector)) { return super.activate(factory, activatedRoute, providers, outletMap); } this.parentRouter.navigate(['/login']); } _canActivate(url) { return this.publicRoutes.indexOf(url) !== -1 || this.userService.isLoggedIn() } } 

userService.isLoggedIn () deve restituire un valore booleano. La mia domanda è: come posso adattare il mio codice per effettuare una chiamata http per verificare se l’utente ha effettuato l’accesso? Perché se il metodo isLoggedIn restituisce un object osservabile e io lo sottoscrivo, non posso restituire il risultato nella funzione genitore.

Si prega di notare che il risultato del metodo di triggerszione di OutletRouter è cambiato.

@ angular / router-deprecato

activate(nextInstruction: ComponentInstruction) : Promise

@ angular / router

activate(factory: ComponentFactory, providers: ResolvedReflectiveProvider[], outletMap: RouterOutletMap) : ComponentRef

che non è più una Promessa o Osservabile. La nuova implementazione del router ha una soluzione leggermente diversa che penso sia più pulita: le guardie.

Il valore di ritorno di una guardia controlla il comportamento del router:

se restituisce true, il processo di navigazione continua se restituisce false, il processo di navigazione si arresta e l’utente rimane inserito. La guardia può anche dire al router di navigare altrove, annullando efficacemente la navigazione corrente.

La guardia potrebbe restituire la sua risposta booleana in modo sincrono. Ma in molti casi, la guardia non può produrre una risposta in modo sincrono. La guardia potrebbe chiedere all’utente una domanda, salvare le modifiche sul server o recuperare nuovi dati. Queste sono tutte operazioni asincrone.

Di conseguenza, una guardia di routing può restituire un osservabile e il router attenderà che l’osservabile si risolva in vero o falso.

Puoi creare auth.guard.ts:

 import { Injectable } from '@angular/core'; import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { UserService } from './user.service'; @Injectable() export class AuthGuard implements CanActivate { constructor(private userService: UserService, private router: Router) {} canActivate( // Not using but worth knowing about next: ActivatedRouteSnapshot, state: RouterStateSnapshot ) { return this.userService.isLoggedIn(); } } 

Ora assicurati che il tuo isLoggedIn return Observable (o Promise) provi entrambi come Angular2 Reference non è ancora pronto ). Nel mio caso l’API restituisce JSON nel formato: {successo: vero / falso}.

 public isLoggedIn() : Observable | boolean { let router: Router = this.router; let obs; try { obs = this.authHttp.get('/api/check/logged') .map(result => result.json()) .map(resultJson => (resultJson && resultJson.success)); } catch (err) { obs = Observable.of(false); } return obs .map(success => { // navigate to login page if (!success) router.navigate(['/auth/login']); return success; }); } 

Quindi modifica l’array RouterConfig:

 { path: '/secret', component: SercetComponent, canActivate: [AuthGuard] } 

Fare riferimento anche alla Guida per lo sviluppatore di Angular2