Angular 2 Child Routes

An example of how child routes and nested directives allow navigation between multiple views when a user clicks a link in a sub-menu.

This tutorial builds on a simple router example and assumes that you have read this tutorial first.

The Application

This application shows how child routes work with a submenu. The parent menu manages the outer colored box and the child menu controls the inner, darker shaded box. It's a working application so feel free to give it a try.

Main Menu

Let's remind ourselves of the main menu which features in the first router example.

The routerLink directives tells the Angular router which path to use, and the appropriate component is used to render a view in the <router-outlet>.

app.component.ts
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
    selector: 'router-app',
    template:  `
        <div>
            <p>
                Parent menu -
                <a routerLink="/red"   routerLinkActive="disabled">Red</a> |
                <a routerLink="/green" routerLinkActive="disabled">Green</a> |
                <a routerLink="/blue"  routerLinkActive="disabled">Blue</a>
            </p>
            <div class="border not-padded">
                <router-outlet></router-outlet>
            </div>    
        </div>`,
    styles: [`
        div {padding: 10px;}
        .not-padded {padding: 0;}
        .border {border: 1px solid #b3b3b3;}
        .disabled {
            pointer-events: none; 
            cursor: default;
            color: #404040;
            text-decoration: none;
        }`
    ],
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
}

Note: to learn more about the routerLink, routerLinkActive and shown in this code snippet, see this Angular 2 router example.

Child Menu

This time the rendered view contains a sub-menu and an additional <router-outlet> directive. When the user clicks a link, a new component is used to render the view here.

At this point the child path is appended to the primary path to produce a URL hash value such as #/green/dark or #/red/medium. You can see this by running the app and watching the browser URL.

There are different ways to set the child route (we demonstrate a few of them here but usually we would be more consistent and just pick one style). We can simply use the child route path and it will be added to the parent route, we can include the parent in an absolute path, or we can specify a relative path using ./ or ../

We now have two levels of menu which control different regions of the page. Next we'll configure the router to handle these nested routes.

blue.component.ts
import { Component } from '@angular/core';

@Component({
    template:  `
        <div class="very-pale-blue padded">
            <h2>Blue</h2>
            <p>
                Child menu -
                <a routerLink="light"        routerLinkActive="disabled">Light Blue</a> |
                <a routerLink="/blue/medium" routerLinkActive="disabled">Medium Blue</a> |
                <a routerLink="./dark"       routerLinkActive="disabled">Dark Blue</a>
            </p>
            <div class="border not-padded">
                <router-outlet></router-outlet>
            </div>
        </div>`,
    styles: ['.very-pale-blue {background-color: #e6e6ff;}']
})
export class BlueComponent {
}

Child Routes

Each parent path (e.g. /red, /green, /blue) has its own set of route definitions. These associate a component with the parent path, and a set of components with the child paths.

So #/blue/light will use BlueComponent to render a view in the outer <router-outlet>, and LightBlueComponent to render the view in the inner <router-outlet>.

blue.routes.ts
import { Routes } from '@angular/router';

import { BlueComponent } from "./blue.component";
import { MediumBlueComponent } from "./medium-blue.component";
import { DarkBlueComponent } from "./dark-blue.component";
import { LightBlueComponent } from "./light-blue.component";

export const BlueRoutes: Routes = [
    {
        path: 'blue',
        component: BlueComponent,
        children: [
            {path: '', redirectTo: 'medium', pathMatch: 'full'},
            {path: 'light', component: LightBlueComponent},
            {path: 'medium', component: MediumBlueComponent},
            {path: 'dark', component: DarkBlueComponent}
        ]
    }
];

Main Routes

These child routes are then added to the main router definition using the JavaScript spread operator. It isn't strictly necessary to split the routes up like this; we could just include the child route definitions directly in this file. However, this technique allows us to group the routes with a particular feature.

app.routes.ts
import { ModuleWithProviders } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";

import { RedRoutes } from "./red/red.routes";
import { GreenRoutes } from "./green/green.routes";
import { BlueRoutes } from "./blue/blue.routes";

export const routes: Routes = [
    {path: '', redirectTo: '/green/medium', pathMatch: 'full'},
    ...RedRoutes,
    ...GreenRoutes,
    ...BlueRoutes
];

export const routing: ModuleWithProviders = RouterModule.forRoot(routes);

Where Next?

To find out more about Angular and TypeScript, check out these tutorials.

  • Hello World - Implement a super-simple <hello-world> custom element using an Angular and TypeScript.
  • The Angular with TypeScript Tutorial - includes examples of components, template syntax, property binding, event binding, bootstrapping and more.
  • Configuration - Configure Angular and TypeScript to download dependencies from node modules or a CDN, and to compile the TypeScript during development or in the browser at runtime.
  • Templates - introduction to inline and external templates.
  • Interpolation - use curly braces and template expressions to output data on the page.
  • Property Binding - bind to DOM properties using square brackets and template expressions.
  • Event Binding - handle DOM events using parentheses and template statements.
  • Two-way Binding - combine property and event binding to create two-way binding with ngModel.
  • Input Binding - bind to <input> fields such as text, textarea, checkbox, radio and select.
  • Built-in Directives - see how to use built-in directives ngIf, ngSwitch, ngFor, ngClass and ngStyle.
  • Component Input Output - use @Input and @Output to pass data in to and out of a component.
  • Angular Router - Use the Angular router to navigate between components when the user clicks a link.