Skip to content

guide routing

Ambuludi Olmedo edited this page Apr 10, 2019 · 5 revisions

Routing

A basic introduction to the Angular Router can be found in Angular Docs.

This guide will show common tasks and best practices.

Defining Routes

For each feature module and the app module all routes should be defined in a seperate module with the suffix RoutingModule. This way the routing modules are the only place where routes are defined. This pattern achieves a clear seperation of concernes. The following figure illustrates this.

Routing module declaration
Figure 1. Routing module declaration

It is important to define routes inside app routing module with .forRoot() and in feature routing modules with .forChild().

Example 1 - No Lazy Loading

In this example two modules need to be configured with routes - AppModule and FlightModule.

The following routes will be configured

  • / will redirect to /search

  • /search displays FlightSearchComponent (FlightModule)

  • /search/print/:flightId/:date displays FlightPrintComponent (FlightModule)

  • /search/details/:flightId/:date displays FlightDetailsComponent (FlightModule)

  • All other routes will display ErrorPage404 (AppModule)

Listing 1. app-routing.module.ts
const routes: Routes = [
  { path: '', redirectTo: 'search', pathMatch: 'full' },
  { path: '**', component: ErrorPage404 }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
Listing 2. flight-search-routing.module.ts
const routes: Routes = [
  {
    path: 'search', children: [
      { path: '', component: FlightSearchComponent },
      { path: 'print/:flightId/:date', component: FlightPrintComponent },
      { path: 'details/:flightId/:date', component: FlightDetailsComponent }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class FlightSearchRoutingModule { }
💡
The import order inside AppModule is important. AppRoutingModule needs to be imported after FlightModule.

Example 2 - Lazy Loading

Lazy Loading is a good practice when the application has multiple feature areas and a user might not visit every dialog. Or at least he might not need every dialog up front.

The following example will configure the same routes as example 1 but will lazy load FlightModule.

Listing 3. app-routing.module.ts
const routes: Routes = [
  { path: '/search', loadChildren: 'app/flight-search/flight-search.module#FlightSearchModule' },
  { path: '**', component: ErrorPage404 }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
Listing 4. flight-search-routing.module.ts
const routes: Routes = [
  {
    path: '', children: [
      { path: '', component: FlightSearchComponent },
      { path: 'print/:flightId/:date', component: FlightPrintComponent },
      { path: 'details/:flightId/:date', component: FlightDetailsComponent }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class FlightSearchRoutingModule { }

Triggering Route Changes

With Angular you have two ways of triggering route changes.

  1. Declarative with bindings in component HTML templates

  2. Programmatic with Angular Router service inside component classes

On the one hand, architecture-wise it is a much cleaner solution to trigger route changes in Smart Components. This way you have every UI event that should trigger a navigation handled in one place - in a Smart Component. It becomes very easy to look inside the code for every navigation, that can occure. Refactoring is also much easier, as there are no navigation events "hidden" in the HTML templates

On the other hand, in terms of accessibility and SEO it is a better solution to rely on bindings in the view - e.g. by using Angulars router-link directive. This way screen readers and the Google crawler can move through the page easily.

💡
If you do not have to support accessibility (screen readers, etc.) and to care about SEO (Google rank, etc.), then you should aim for triggering navigations only in Smart Components.
Triggering navigation
Figure 2. Triggering navigation
Clone this wiki locally