16

I've read this question about how to determine the active route, but still it's not clear to me how to determine an active route with paramaters?

Right now I'm doing it like this:

<a [routerLink]="['/Profile/Feed', {username: username}]"
   [ngClass]="{active: getLinkStyle('/profile/john_doe/feed')}">
   Feed for {{username}}
</a>

And inside my component:

getLinkStyle(path:string):boolean {
  console.log(this._location.path()); // logs: '/profile/john_doe/feed'
  return this._location.path() === path;
}

And this will work because I'm passing the username as a string. Is there any way to do this with passing the correct parameter??

Lazar Ljubenović
  • 18,976
  • 10
  • 56
  • 91
Aico Klein Ovink
  • 1,647
  • 2
  • 14
  • 21

8 Answers8

19

With the new, up and coming Angular 2 router (at version 3.0-alpha.7 as I write this), it's very simple.

All you need to do is use the [routerLinkActive] directive in your link.

<a [routerLinkActive]="['active']" [routerLink]="['/contact',  contact.id ]">
    {{contact.name}}
</a>

This is what you will be using when Angular 2 is released for real, and no longer a release candidate. I'm using the alpha of the router now and not having any issues.

Here's Plunk demonstrating it. You can see that the links go red as you click on them. That's the directive assigning the active class to them. You could use any class name of your choosing, of course.

Michael Oryl
  • 20,856
  • 14
  • 77
  • 117
8

Just check the auto-defined router-link-active class to a element.

iuristona
  • 927
  • 13
  • 30
  • Did they implement that on the beta 2 version? – Aico Klein Ovink Jan 27 '16 at 22:29
  • 2
    Is it possible to automatically set an `active` class if the `router-link-active` class is applied? Because most CSS templates will require other class names and I don't want to modify the template. @AicoKleinOvink Afaik it was already there in the latest alpha versions. – berhir Jan 28 '16 at 11:08
  • They implemented on the 2.0.0-alpha.37 (2015-09-09) to be exactly. https://github.com/angular/angular/issues/3209 – iuristona Jan 28 '16 at 12:28
  • I couldnt change the default css name, it is hard-coded. I am saw that exists a isRouteActive: boolean property for each [routerLink] but I am not able to reference it. – iuristona Jan 28 '16 at 12:34
  • Seems `routerLinkActive` directive only works on `Link Params( /foo/bar )`, not for `Query Params ( /foo;value=bar )`. – Francis.TM Jul 08 '16 at 14:49
6

In Angular 2 rc1 router.isRouteActive does not exist anymore. I could not find a working solution anywhere, but I was able to solve it like this (the custom method isActiveRoute does the trick):

App.component.ts:

import { Component } from '@angular/core';
import { Routes, Route, Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router';
import { HomeComponent } from './home.component';
import { P1Component } from './p1.component';

@Component({
    selector: 'app',
    templateUrl: './app/app.template.html',
    directives: [ROUTER_DIRECTIVES]
})

@Routes([
    { path: '/', component: HomeComponent },
    { path: '/p1', component: P1Component }
])

export class AppComponent implements OnInit {

    constructor(public router: Router){ }

    isActiveRoute(route: string) {
        return this.router.serializeUrl(this.router.urlTree) == this.router.serializeUrl((this.router.createUrlTree([route])));
    } 
}

App.template.html:

            <ul class="nav navbar-nav">
                <li [class.active]="isActiveRoute('/')">
                    <a class="nav-link" [routerLink]="['/']">Home</a>
                </li>
                <li [class.active]="isActiveRoute('/p1')">
                    <a class="nav-link" [routerLink]="['/p1']">Page 1</a>
                </li>
Mcanic
  • 1,304
  • 16
  • 22
5

I've been trying to set the active class without having to know exactly what's the current location (using the route name). This is the best solution I have got to so far.

This is how the RouteConfig looks like (I've tweaked it a bit to look like what you want to do):

@RouteConfig([
  { path: '/', component: HomePage, as: 'Home' },
  { path: '/signin', component: SignInPage, as: 'SignIn' },
  { path: '/profile/:username/feed', component: FeedPage, as: 'ProfileFeed' },
])

And the View would look like this:

<li [class.active]="router.isRouteActive(router.generate(['/Home']))">
   <a [routerLink]="['/Home']">Home</a>
</li>
<li [class.active]="router.isRouteActive(router.generate(['/SignIn']))">
   <a [routerLink]="['/SignIn']">Sign In</a>
</li>
<li [class.active]="router.isRouteActive(router.generate(['/ProfileFeed', { username: user.username }]))">
    <a [routerLink]="['/ProfileFeed', { username: user.username }]">Feed</a>
</li>

This has been my preferred solution for the problem so far, it might be helpful for you as well.

Alex Santos
  • 2,900
  • 1
  • 19
  • 21
  • That looks promising, will look into that tomorrow!! Much appreciated! – Aico Klein Ovink Jan 03 '16 at 00:05
  • Still think something like ui-sref-active from the awesome ui-router would be great.. – Aico Klein Ovink Jan 03 '16 at 00:07
  • Ok, I tried your solution @Alex, but can't get it to work. This is the actual piece of my code: `

    Profiel
    `
    – Aico Klein Ovink Jan 05 '16 at 11:24
  • It looks correct, are you getting errors by any chances (if you are what would those be)? Just a reminder, you need to import the `Router`. `import {ROUTER_DIRECTIVES, Router} from 'angular2/router';` – Alex Santos Jan 05 '16 at 14:45
  • When I `console.log(router.generate(['/Profile/Feed', {username: profileUser.username}])` it return this object: `ResolvedInstruction {auxInstruction: Object, component: ComponentInstruction, child: ResolvedInstruction}` – Aico Klein Ovink Jan 05 '16 at 14:53
  • Do you mind sharing your `RouteConfig` as well? Looking at the name of your route, it seems like `Feed` is a "subcomponent" of `Profile`. (Edited, mixed my thoughts) – Alex Santos Jan 05 '16 at 14:59
  • Regarding the output of the generate function, it looks correct, I've just tested the things you've sent me on an angular 2 app and it all works fine. Here's what I have: https://gist.github.com/Colex/658e534159027ecfc60b – Alex Santos Jan 05 '16 at 15:09
  • Here is my [gist](https://gist.github.com/aicokleinovink/f9f0df3fb28a78c613f2#file-profile-header-html), for the record: I've rewritten it back to the old way.. Maybe you can have a look! – Aico Klein Ovink Jan 06 '16 at 10:53
  • @AlexCorreiaSantos This works. Thanks! I would like to know how does the `router:Router` got injected? Since the `Router` class doesn't appear in any `providers` array, how can Angular know what to inject? – LShi Apr 17 '16 at 16:01
  • @LS.Shanghai You can just add `public router: Router` as an argument to the component's constructor. – František Žiačik May 15 '16 at 11:28
  • In Angular2 rc1, you need to update to something like this: `[class.active]="router.urlTree.contains(router.createUrlTree(['Home']))"` – František Žiačik May 15 '16 at 11:30
1

You can use new Location service from Angular2 common package: https://angular.io/docs/js/latest/api/router/Location-class.html#!#path-anchor

import { Location } from '@angular/common';

...

export class YourClass {
    constructor(private _loc:Location) {}

    getCurrentPath() {
        return this._loc.path();
    }
}

Note: it's better to use Router service to trigger route changes. Use Location only if you need to interact with or create normalized URLs outside of routing.

Please note: Documentation says import from router, but the latest betta version I have has Location services in common.

Brian
  • 4,958
  • 8
  • 40
  • 56
1

try this :

<li   class="ann_profileimg" [routerLinkActive]="['active']" [routerLink]="['profile']">
            <div class="ann_header_menu_left ann_profile_avatar_small"></div>
            <span>Vishnu </span>
          </li>
VISHNU
  • 948
  • 8
  • 15
0

For Angular version 4+, determining a active route in the template is fairly easy as there is a build-in directive for this purpose name routerLinkActive which you can use the following way:

      <li class="nav-item" routerLinkActive="active">
        <a class="nav-link" routerLink="/home">Home</a>
      </li>
      <li class="nav-item" routerLinkActive="active">
        <a class="nav-link" routerLink="/about-us">About Us</a>
      </li>
      <li class="nav-item" routerLinkActive="active">
        <a title="Contact Us" class="nav-link " routerLink="/contact-us">Contact</a>
      </li>
    </ul>
asmmahmud
  • 4,844
  • 2
  • 40
  • 47
0
<a [routerLink]="['/Profile/Feed', {username: username}]"
routerLinkActive="active-item" [routerLinkActiveOptions]="{exact: false}">
   Feed for {{username}}
</a>

active-item is your css class which you want to give for active menu. routerLinkActive is used for giving css for active menu, where as routerLinkActiveOptions will tell you whether you want the url to be matched exactly. this usually helps in where you have same url for create and edit (with param)

example:

for create:

http://localhost/feed

for edit:

http://localhost/feed/1

Ayesha
  • 251
  • 2
  • 7