Angular 2 Routing - Tuong-Nguyen/Angular-D3-Cometd GitHub Wiki

Angular Routing allows partial of the page is loaded instead of the whole page.

Add router to a component

  • Add router-outlet into the component template
@Component({
  selector: "events-app",
  template: `
    <nav-bar></nav-bar>
    <router-outlet></router-outlet>
  `,
})
export class EventsAppComponent {

}
  • Define routes
export const appRoutes: Routes = [
  {path: "events", component: EventsListComponent },
  {path: "events/:id", component: EventDetailsComponent},
  {path: "", redirectTo: "events", pathMatch: "full"},
];
  • Set Root routes in module file
  imports: [
    BrowserModule,
    RouterModule.forRoot(appRoutes),
  ],
  • Set base in index.html file (page contains the component)
<base href="/">

Link to route

routerLink can be used for linking an element to a route.

<div [routerLink]="['/events', event.id]" class="well hoverwell thumbnail">
</div>
  • [routerLink]="['/events', event.id]" <=> routerLink="{{['events', event.id]}}"

Accessing route's parameter

  • Component can access route's parameter using ActivatedRoute instance which is injected through constructor
constructor(private route: ActivatedRoute) {}
// for route
  {path: "events/:id", component: EventDetailsComponent}

// id parameter can be accessed as:
  id = this.route.snapshot.params["id"];
  • When route changes, we need to subscribe params observable to get new params
  this.route.params.subscribe(
     (params: Params) => {
        id = params["id"];
     }
  )
  • Angular unsubcribe the subscription automatically when the component is destroyed

Query parameters & Fragment

Pass to route

  • queryParams is a key-value object
<a routerLink="/users" [queryParams]="{allowEdit: '1'}">User name</a>
<!-- http://localhost:4200/users?allowEdit=1 -->
  • fragment is string value
<a routerLink="/users" fragment="loading">User name</a>
<!-- http://localhost:4200/users#loading -->

Retrieve in component

Similar to params, we can get queryParams and fragment from <ActivatedRoute>.snapshot.queryParams and <ActivatedRoute>.snapshot.fragment or subscribe the <ActivatedRoute>.queryParams or <ActivatedRoute>.fragment

Navigating from code

  • Router instance can be used in Component for navigating to route
export class UsersComponent {
  // inject Router instance
  constructor(private router:Router){}

  public cancel (){
    // navigate to a route
    this.router.navigate(["/users/events"]);
  }
}
  • To use relative route, we can add relativeTo a route parameter
this.router.navigate(["events"], {relativeTo: this.route})

Nested Routes

  • Use children property of Route
const appRoutes: Routes = [
  {path: 'widgets', component: WidgetsComponent, children: [
     {path: 'new', component: AddWidgetComponent}
  ]}
];
  • In parent component's template, use <router-outlet></router-outlet> to load child component

Guarding route

CanActivate

  • Route's canActivate property can be used for not allowing to access the route. It can be set to a service (ex: EventRouteActivator) which implement CanActivate interface.
// Service implements CanActivate interface for guarding the route
export class EventRouteActivator implements CanActivate {
  constructor(private eventService: EventService, private router:Router) {}

  public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
    Observable<boolean> | Promise<boolean> | boolean {

    let eventExist = !!this.eventService.getEvent(route.params["id"]);
    if(!eventExist){
      this.router.navigate(["/404"]);
    }
    return eventExist;
  }
}
  • Apply to a route
{path: "events/:id", component: EventDetailsComponent, canActivate: [EventRouteActivator]}

CanActivateChild

  • Similar to CanActivate
  • Runs before any child route is activated
const adminRoutes: Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [AuthGuard],
    children: [
      {
        path: '',
        canActivateChild: [AuthGuard],
        children: [
          { path: 'heroes', component: ManageHeroesComponent },
          { path: '', component: AdminDashboardComponent }
        ]
      }
    ]
  }
];
export class AuthGuard implements CanActivate, CanActivateChild {
   // ...
   canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
      // implementation
   }
}

CanDeactivate

Route's CanDeactivate property is used for not allowing user to move out of the route.

// Service implements CanActivate interface for guarding the route
export class EventRouteDeactivator implements CanDeactivate<Component> {
  constructor(private eventService: EventService, private router:Router) {}

  public canDeactivate(component: Component, route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
    Observable<boolean> | Promise<boolean> | boolean {
     return true;
  }
}
⚠️ **GitHub.com Fallback** ⚠️