首页 > 代码库 > [Angular2 Router] CanActivate Route Guard - An Example of An Asynchronous Route Guard

[Angular2 Router] CanActivate Route Guard - An Example of An Asynchronous Route Guard

In this tutorial we are going to learn how we can to configure an can activate route guard in the Angular 2 router. We are going to implement the concrete example where a user can only enter a certain route if its authorized to do so. We are also going to give in this tutorial an example of how a route guard can also make asynchronous calls, by returning an observable that will eventually resolve to true or false.

 

hero-can-activate.ts:

import {CanActivate, RouterStateSnapshot, ActivatedRouteSnapshot} from "@angular/router";import {Observable, Subject} from "rxjs";import {StarWarsService} from "./heros.service";import {Injectable} from "@angular/core";@Injectable()export class CanHeroActivateDirective implements CanActivate{  constructor(private sws: StarWarsService){  }  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|boolean {    if(this.sws.people){      const sub = new Subject<boolean>();      setTimeout( () => {        const id = route.params[id];        const hero = this.sws.people.find( (p) => {          return Number(p.id) === Number(id);        });        sub.next(hero.mass !== "unknown");        sub.complete();      });      return sub;    }else{      return true;    }  }}

 

heros.service.ts:

import {Injectable, Inject} from @angular/core;import {STARWARS_BASE_URL} from "../shared/constance.service";import {Http} from "@angular/http";import "rxjs/add/operator/map";import "rxjs/add/operator/switchMap";@Injectable()export class StarWarsService {    people:any;    constructor(@Inject(STARWARS_BASE_URL) private starwarUrl,      private http: Http    ) {}    getPeople(){      return this.http.get(`${this.starwarUrl}/people`)        .map( res => res.json())        .do( res => this.people = res)    }    getPersonDetail(id){      return this.http.get(`${this.starwarUrl}/people/${id}`)        .map( res => res.json())        .map( (hero:any) => Object.assign({}, hero, {          image: `${this.starwarUrl}/${hero.image}`        }))    }}

 

heros.routes.ts:

import {HerosComponent} from "./heros.component";import {RouterModule} from "@angular/router";import {HeroComponent} from "./hero/hero.component";import {CanHeroDeactivate} from "./heros-can-deactivate.directive";import {CanHeroActivateDirective} from "./heros-can-activate.directive";const routes = [  {path: ‘‘, component: HerosComponent},  {path: :id, component: HeroComponent, canDeactivate: [CanHeroDeactivate], canActivate: [CanHeroActivateDirective]},];export default RouterModule.forChild(routes)

 

hero.module.ts:

import { NgModule } from @angular/core;import { CommonModule } from @angular/common;import { HerosComponent } from ./heros.component;import herosRoutes from ./heros.routes;import {HeroComponent} from "./hero/hero.component";import {StarWarsService} from "./heros.service";import {RouterModule} from "@angular/router";import {CanHeroDeactivate} from "./heros-can-deactivate.directive";import {CanHeroActivateDirective} from "./heros-can-activate.directive";@NgModule({  imports: [    CommonModule,    herosRoutes  ],  declarations: [HerosComponent, HeroComponent],  providers: [StarWarsService, CanHeroDeactivate, CanHeroActivateDirective]})export default class HerosModule { }

 

Github

[Angular2 Router] CanActivate Route Guard - An Example of An Asynchronous Route Guard