Monday, September 5, 2016

Appendix 2 Routing

Basic Routes

To enable routing, make sure that in index.html, you have

<base href="/">

Define route in a separate file.

New file, app.routing.ts

app.routing.ts

import { Router, RouterModule } from '@angular/router';

import {HomeComponent} from './home.component';
import {PhotosComponent} from './photos/photos.component';
import {MessagesComponent} from './messages/messages.component';
import {NotFoundComponent} from './not-found.component';

// how to define route
export const routing = RouterModule.forRoot([
    { path: '', component: HomeComponent},
    { path: 'messages', component: MessagesComponent},
    { path: 'photos', component: PhotosComponent},
    { path: '**', component: NotFoundComponent} // wildcard for any other route
]);

app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent }  from './app.component';
import { HomeComponent } from './home.component';
import { NotFoundComponent } from './not-found.component';

import { MessagesModule } from './messages/messages.module'; 
import { PhotosModule } from './photos/photos.module';

import {routing} from './app.routing';

@NgModule({
  imports: [
    BrowserModule,
    MessagesModule,
    PhotosModule,
    routing
  ],
  declarations: [ 
    AppComponent,
    HomeComponent,
    NotFoundComponent
  ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <ul>
      <li><a routerLink="">Home</a></li>
      <li><a routerLink="messages">Messages</a></li>
      <li><a routerLink="photos">Photos</a></li>
    </ul>
    <router-outlet></router-outlet>
`
})
export class AppComponent {
}

Parameterised Routes

app.routing.ts

import { Router, RouterModule } from '@angular/router';

import {HomeComponent} from './home.component';
import {PhotosComponent} from './photos/photos.component';
import {PhotoDetailsComponent} from './photos/photo-details.component';
import {MessagesComponent} from './messages/messages.component';
import {NotFoundComponent} from './not-found.component';

// how to define route
export const routing = RouterModule.forRoot([
    { path: '', component: HomeComponent},
    { path: 'messages', component: MessagesComponent},
    { path: 'photos/:id', component: PhotoDetailsComponent},
    { path: 'photos', component: PhotosComponent},
    { path: '**', component: NotFoundComponent} // wildcard for any other route

]);

app.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'my-app',
  template: `
    <ul>
      <li><a routerLink="">Home</a></li>
      <li><a routerLink="messages">Messages</a></li>
      <li><a routerLink="photos">Photos</a></li>
      <li><a [routerLink]="['photos',1]">Photo Details</a></li>
    </ul>
    <button (click)="onClick()">Click Me</button>
    <router-outlet></router-outlet>  
`
})
export class AppComponent {
  constructor(private _router: Router){

  }

  onClick(){
    this._router.navigate(['photos',2]);
  }


}

photo-details.component.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
    template: `<h1>Photo Details {{ id }}</h1>
    `
})
export class PhotoDetailsComponent implements OnInit, OnDestroy{

    id;
    subscription;

    constructor(private _route: ActivatedRoute){
        
    }

    ngOnInit(){        
        this.subscription = this._route.params.subscribe(params => {
            this.id = params["id"];
        });        
    }

    ngOnDestroy(){ 
        this.subscription.unsubscribe();
    }

}

Feature Module Routes

Move routes in each feature area to its corresponding module. We have two modules now, messages, and photos.

In photos folder, add a new file, photos.routing.ts

import { Router, RouterModule } from '@angular/router';

import {PhotosComponent} from './photos.component';
import {PhotoDetailsComponent} from './photo-details.component';

// this is a child module, We use forRoot only for app.module which is the root of our app
export const photosRouting = RouterModule.forChild([
    { path: 'photos/:id', component: PhotoDetailsComponent},
    { path: 'photos', component: PhotosComponent} 
]);

app.routing.ts

import { Router, RouterModule } from '@angular/router';

import {HomeComponent} from './home.component';
import {PhotosComponent} from './photos/photos.component';
import {PhotoDetailsComponent} from './photos/photo-details.component';
import {MessagesComponent} from './messages/messages.component';
import {NotFoundComponent} from './not-found.component';

export const routing = RouterModule.forRoot([
    { path: '', component: HomeComponent},
    { path: 'messages', component: MessagesComponent},
    { path: 'photos/:id', component: PhotoDetailsComponent},
    { path: 'photos', component: PhotosComponent},
    { path: '**', component: NotFoundComponent} 
]);

This makes our app routing cleaner and more mainable.

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent }  from './app.component';
import { HomeComponent } from './home.component';
import { NotFoundComponent } from './not-found.component';

import { MessagesModule } from './messages/messages.module'; 
import { PhotosModule } from './photos/photos.module';

import {routing} from './app.routing';
import {photosRouting} from './photos/photos.routing';

@NgModule({
  // always import feature module routes before main routes
  imports: [
    BrowserModule,
    MessagesModule,
    PhotosModule,
    photosRouting,
    routing    
  ],
  declarations: [ 
    AppComponent,
    HomeComponent,
    NotFoundComponent
  ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

No comments:

Post a Comment