Книга: Angular 2 Cookbook
Назад: Selecting a LocationStrategy for path construction
Дальше: Implementing nested views with route parameters and child routes

Building stateful route behavior with RouterLinkActive

It is often the case when building applications that you will want to build features that would involve which page the application is currently on. When this is a one-time inspection, it isn't a problem, as both Angular and default browser APIs allow you to easily inspect the current page.

Things get a bit stickier when you want the state of the page to reflect the state of the URL, for example, if you want to visually indicate which link corresponds to the current page. A from-scratch implementation of this would require some sort of state machine that would know when navigation events occur and what and how to modify at each given route.

Fortunately, Angular 2 gives you some excellent tools to do this right out of the box.

Note

The code, links, and a live example of this are all available at .

Getting ready

Begin with the Array and anchor-tag-based implementation shown in the Navigating with routerLinks recipe.

Your goal is to use RouterLinkActive to introduce some simple stateful route behavior.

How to do it...

RouterLinkActive allows you to conditionally apply classes when the current route matches the corresponding routerLink on the same element. Proceed directly to adding it as an attribute directive to each link as well as a matching CSS class:

[app/root.component.ts]      import {Component} from '@angular/core';      @Component({     selector: 'root',     template: `       <h1>Root component</h1>       <a [routerLink]="['']"          [routerLinkActive]="'active-navlink'">Default</a>       <a [routerLink]="['article']"          [routerLinkActive]="'active-navlink'">Article</a>       <router-outlet></router-outlet>     `,     styles: [`       .active-navlink {         color: red;          text-transform: uppercase;       }     `]   })   export class RootComponent {}   

This is all you need for links to become active! You will notice that Angular will conditionally apply the active-navlink class based on the current route.

However, when testing this, you will notice that the /article route makes both the links appear active. This is due to the fact that by default, Angular marks all routerLinks that match the current route as active.

Note

This behavior is useful in cases where you may want to show a hierarchy of links as active for example, at route /user/123/detail, it could make sense that the separate links /user, /user/123, and /user/123/detail are all shown as active.

However, in the case of this recipe, this behavior is not useful to you, and Angular has another router directive, routerLinkActiveOptions, which binds to an options object. The exact property inside the options object is useful in this case; it controls whether the active state should only be applied in cases of an exact match:

[app/root.component.ts]      import {Component} from '@angular/core';   import {Router} from '@angular/router';      @Component({     selector: 'root',     template: `       <h1>Root component</h1>       <a [routerLink]="['']"          [routerLinkActive]="'active-navlink'"          [routerLinkActiveOptions]="{exact:true}">Default</a>       <a [routerLink]="['article']"          [routerLinkActive]="'active-navlink'"          [routerLinkActiveOptions]="{exact:true}">Article</a>       <router-outlet></router-outlet>     `,     styles: [`       .active-navlink {         color: red;          text-transform: uppercase;       }     `]   })   export class RootComponent {}   

Now you will find that each link will only be active at its respective route.

How it works...

The routerLinkActive implementation subscribes to navigation change events that Angular emits from the Router service. When it sees a NavigationEnd event, it performs an update of all the attached HTML tags, which includes adding and stripping applicable "active" CSS classes that the element is bound to via the directive.

There's more...

If you need to bind routerLinkActive to a dynamic value, the preceding syntax will allow you to do exactly that. For example, you can bind to a

component

member and

modify

it elsewhere, and Angular will handle everything for you. However, if this is not required, Angular will handle routerLinkActive without the data binding brackets. In this case, the value of the directive no longer needs to be an Angular expression, so you can remove the nested quotes.

The following is behaviorally identical:

[app/root.component.ts]      import {Component} from '@angular/core';   import {Router} from '@angular/router';      @Component({     selector: 'root',     template: `       <h1>Root component</h1>       <a [routerLink]="['']"          routerLinkActive="active-navlink"          [routerLinkActiveOptions]="{exact:true}">          Default</a>       <a [routerLink]="['article']"          routerLinkActive="active-navlink"          [routerLinkActiveOptions]="{exact:true}">          Article</a>       <router-outlet></router-outlet>     `,     styles: [`       .active-navlink {         color: red;          text-transform: uppercase;       }     `]   })   export class RootComponent {}   

See also

  • Setting up an application to support simple routes shows you the basics of Angular routing
  • Navigating with routerLinks demonstrates how to navigate around Angular applications
  • Building stateful RouterLink behavior with RouterLinkActive shows how to integrate application behavior with a URL state
  • Implementing nested views with route parameters and child routes gives an example of how to configure Angular URLs to support nesting and data passing
  • Adding route authentication controls with route guards details the entire process of configuring protected routes in your application
Назад: Selecting a LocationStrategy for path construction
Дальше: Implementing nested views with route parameters and child routes

thank you
Flame
cant read the code since it is all on a single line. Also this comments section is russian
Rakuneque
DATA COLLECTION AND ANALYSIS Two reviewers extracted data and assessed methodological quality independently lasix torsemide conversion Many others were in that space already