The router directives – RouterOutlet and RouterLink

The ROUTER_DIRECTIVES symbol gives us access to the only two directives we will need in our applications.

First, the RouterOutlet directive is the placeholder directive where the different components whose paths have been navigated to by the user will be rendered. The RouterLink is used as an attribute directive to help the HTML controls behave as anchors or link buttons leading to the different routes by specifying the unique name each route is configured with, as we will see next.

In the previous chapters, we configured our top root component template to display a cute nav bar header, followed by the custom elements representing the Pomodoro timer and the tasks list. Now, we will strip the HTML template out from the component decorator definition and save it into its own template file, in order to access it more conveniently when editing the HTML is required. Also, we will refactor it into a router-friendly component template with links pointing to the different views or states our application can feature, as follows:

app/app.component.ts

   ...
   @Component({
  selector: 'pomodoro-app',
  directives: [ROUTER_DIRECTIVES],
  providers: [SHARED_PROVIDERS, HTTP_PROVIDERS, ROUTER_PROVIDERS],
  templateUrl: 'app/app.component.html'
})
...

app/app.component.html

<nav class="navbar navbar-default navbar-static-top">
  <div class="container">
    <div class="navbar-header">
      <strong class="navbar-brand">My Pomodoro App</strong>
    </div>
    <ul class="nav navbar-nav navbar-right">
      <li><a [routerLink]="['TasksComponent']">Tasks</a></li>
      <li><a [routerLink]="['TimerComponent']">Timer</a></li>
      <li><a [routerLink]="['TaskEditorComponent']">
          Publish Task</a>
      </li>
    </ul>
  </div>
</nav>

<router-outlet></router-outlet>

As you can see in the template, the location where the components used to live has been replaced by the <router-outlet> directive, and three new links compound up our beautiful nav bar. Reload the page and see how our tasks list is rendered on the screen, and then click on the Timer link. Awesome! The TimerComponent item just loaded on the screen. Click on the other link or hit back on your browser to see how you can jump across the different components seamlessly.

Let’s take a look at these links more closely, taking the link pointing to the timer as an example:

<a [routerLink]="['TimerComponent']">Timer</a>

The morphology of the routerLink directive is pretty self-explanatory. On the right-hand side of the equal symbol, it expects an array of route names corresponding to the named route and, optionally, the subroutes within the former that we want to navigate to. Most of the time, we will just see one unique string value. However, the array can allocate many values depending on whether the component whose named path we are pointing to hosts its own router with named routes as well. In this case, the subroute names we want to load will be declared next in the strings array. This is why it is so convenient and recommended to name our routes after the components they point at.

Note

The new Release Candidate Router deprecates named routes, favoring URL paths instead. Therefore, the [routerLink] directive will expect a full path as a value.

The routerLink definition also leaves room to add parameters declaratively, so we can trigger dynamic routes at runtime. We will tap into all these features throughout the next sections, but now we need to answer one important question. What if we want to navigate to a component imperatively without actually clicking on a link, but rather as the by-product of an action performed within the component’s controller class?