En angle, comment déterminez-vous la voie active?

NOTE: il y a beaucoup de réponses différentes ici, et la plupart ont été valables à un moment ou à un autre. Le fait est que ce qui fonctionne a changé un certain nombre de fois que L'équipe angulaire a changé son routeur. La version de routeur 3.0 qui sera éventuellement le routeur dans les pauses angulaires beaucoup de ces solutions, mais offre une solution très simple de ses propres. Comme de RC.3, la solution préférée est d'utiliser [routerLinkActive] comme indiqué dans cette réponse .

en application angulaire (courant dans le 2.0.0-beta.0 version que j'écris ceci), comment déterminez-vous la route?

je travaille sur une application qui utilise Bootstrap 4 et j'ai besoin d'un moyen de marquer les liens/boutons de navigation comme actifs lorsque leur composant associé est affiché dans une étiquette <router-output> .

je me rends compte que je pourrais maintenir l'état moi-même quand un des boutons est cliqué dessus, mais cela ne couvrirait pas le cas d'avoir plusieurs chemins dans la même route (disons un menu de navigation principal aussi bien qu'un menu local dans le composant principal).

toute suggestion ou lien serait apprécié. Grâce.

216
demandé sur Lazar Ljubenović 2015-12-17 01:37:56

25 réponses

avec le nouveau routeur angulaire , vous pouvez ajouter un attribut [routerLinkActive]="['your-class-name']" à tous vos liens:

<a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a>

ou le format simplifié sans tableau si une seule classe est nécessaire:

<a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a>

voir la mal documenté routerLinkActive directive pour plus d'information. (J'ai surtout compris par essai et erreur.)

mise à jour: meilleure documentation pour le routerLinkActive la directive se trouve maintenant ici . (Merci à @Victor Hugo Arango A. dans les commentaires ci-dessous.)

259
répondu jessepinho 2018-08-24 16:25:35

j'ai répondu ceci dans une autre question mais je crois que cela pourrait être pertinent pour celui-ci aussi bien. Voici un lien vers la réponse originale: Angulaire 2: Comment déterminer l'itinéraire actif avec les paramètres?

j'ai essayé de définir la classe active sans avoir à savoir exactement quel est l'emplacement actuel (en utilisant le nom de route) . La meilleure solution que j'ai jusqu'à présent est d'utiliser la fonction isRouteActive disponible dans la classe Router .

router.isRouteActive(instruction): Boolean prend un paramètre qui est une route Instruction objet et retourne true ou false que cette instruction soit vraie ou non pour la route actuelle. Vous pouvez générer une route Instruction en utilisant Router 's générer(linkParams: Array) . LinkParams suit exactement le même format qu'une valeur transmise dans un routerLink directive (par exemple router.isRouteActive(router.generate(['/User', { user: user.id }])) ).

voilà comment le RouteConfig pourrait ressembler à (j'ai modifié un peu pour montrer l'usage des params) :

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

et le View ressemblerait à ceci:

<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>

cela a été ma solution préférée pour le problème jusqu'à présent, il pourrait être utile pour vous comme bien.

64
répondu Alex Santos 2017-05-23 11:47:36

j'ai résolu un problème que j'ai rencontré dans ce lien et je découvre qu'il ya une solution simple pour votre question. Vous pouvez utiliser router-link-active à la place dans vos styles.

@Component({
   styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
32
répondu Quy Tang 2017-05-23 12:18:36

petite amélioration à la réponse de @alex-correia-santos basée sur https://github.com/angular/angular/pull/6407#issuecomment-190179875

import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
// ...
export class App {
  constructor(private router: Router) {
  }

  // ...

  isActive(instruction: any[]): boolean {
    return this.router.isRouteActive(this.router.generate(instruction));
  }
} 

et l'utiliser comme ceci:

<ul class="nav navbar-nav">
    <li [class.active]="isActive(['Home'])">
        <a [routerLink]="['Home']">Home</a>
    </li>
    <li [class.active]="isActive(['About'])">
        <a [routerLink]="['About']">About</a>
    </li>
</ul>
28
répondu tomaszbak 2016-06-07 20:52:37

vous pouvez vérifier la route courante en injectant l'objet Location dans votre contrôleur et en cochant le path() , comme ceci:

class MyController {
    constructor(private location:Location) {}

    ...  location.path(); ...
}

Vous devrez vous assurer de l'importer:

import {Location} from "angular2/router";

vous pouvez alors utiliser une expression régulière pour faire correspondre avec le chemin qui est retourné pour voir quelle route est active. Notez que la classe Location renvoie un chemin normalisé indépendamment du LocationStrategy que vous utilisez. Donc, même si vous utilisez le HashLocationStragegy les chemins retournés seront toujours du formulaire /foo/bar pas #/foo/bar

27
répondu Jason Teplitz 2016-01-05 02:55:40

comment déterminez-vous la route?

mise à jour: mise à jour selon Angular2.4.x

constructor(route: ActivatedRoute) {
   route.snapshot.params; // active route's params

   route.snapshot.data; // active route's resolved data

   route.snapshot.component; // active route's component

   route.snapshot.queryParams // The query parameters shared by all the routes
}

voir plus...

14
répondu Ankit Singh 2016-12-27 10:09:21

ci-dessous est la méthode utilisant RouteData pour style menuBar articles en fonction de la route actuelle:

RouteConfig comprend des données avec la touche tab (actuelle route):

@RouteConfig([
  {
    path: '/home',    name: 'Home',    component: HomeComponent,
    data: {activeTab: 'home'},  useAsDefault: true
  }, {
    path: '/jobs',    name: 'Jobs',    data: {activeTab: 'jobs'},
    component: JobsComponent
  }
])

Un morceau de la mise en page:

  <li role="presentation" [ngClass]="{active: isActive('home')}">
    <a [routerLink]="['Home']">Home</a>
  </li>
  <li role="presentation" [ngClass]="{active: isActive('jobs')}">
    <a [routerLink]="['Jobs']">Jobs</a>
  </li>

Classe:

export class MainMenuComponent {
  router: Router;

  constructor(data: Router) {
    this.router = data;
  }

  isActive(tab): boolean {
    if (this.router.currentInstruction && this.router.currentInstruction.component.routeData) {
      return tab == this.router.currentInstruction.component.routeData.data['activeTab'];
    }
    return false;
  }
}
6
répondu Ivan 2016-04-15 09:07:47

voici un exemple complet pour ajouter le style de route active dans la version angulaire 2.0.0-rc.1 qui prend en compte les chemins de racine nuls (par exemple path: '/' )

app.composant.ts - > Routes

import { Component, OnInit } from '@angular/core';
import { Routes, Router, ROUTER_DIRECTIVES } from '@angular/router';
import { LoginPage, AddCandidatePage } from './export';
import {UserService} from './SERVICES/user.service';

@Component({
  moduleId: 'app/',
  selector: 'my-app',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css'],
  providers: [UserService],
  directives: [ROUTER_DIRECTIVES]
})

@Routes([
  { path: '/', component: AddCandidatePage },
  { path: 'Login', component: LoginPage }
])
export class AppComponent  { //implements OnInit

  constructor(private router: Router){}

  routeIsActive(routePath: string) {
     let currentRoute = this.router.urlTree.firstChild(this.router.urlTree.root);
     // e.g. 'Login' or null if route is '/'
     let segment = currentRoute == null ? '/' : currentRoute.segment;
     return  segment == routePath;
  }
}

app.composant.html

<ul>
  <li [class.active]="routeIsActive('Login')"><a [routerLink]="['Login']" >Login</a></li>
  <li [class.active]="routeIsActive('/')"><a [routerLink]="['/']" >AddCandidate</a></li>
</ul>
<route-outlet></router-outlet>
6
répondu Levi Fuller 2016-06-11 17:21:47

Solution pour Angular2 RC 4:

import {containsTree} from '@angular/router/src/url_tree';
import {Router} from '@angular/router';

export function isRouteActive(router: Router, route: string) {
   const currentUrlTree = router.parseUrl(router.url);
   const routeUrlTree = router.createUrlTree([route]);
   return containsTree(currentUrlTree, routeUrlTree, true);
}
6
répondu lukaville 2016-07-12 12:09:40

en ce moment j'utilise rc.4 avec bootstrap 4 et celui-ci fonctionne parfaitement pour moi:

 <li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact:
true}">
    <a class="nav-link" [routerLink]="['']">Home</a>
</li>

Ce sera un travail pour l'url : /home

6
répondu Artem Zinoviev 2016-08-10 12:28:21

pour marquer les routes actives routerLinkActive peut être utilisé

<a [routerLink]="/user" routerLinkActive="some class list">User</a>

cela fonctionne aussi sur d'autres éléments comme

<div routerLinkActive="some class list">
  <a [routerLink]="/user">User</a>
</div>

Si les correspondances partielles devrait également être marquée utiliser

routerLinkActive="some class list" [routerLinkActiveOptions]="{ exact: false }"

autant que je sache exact: false va être la valeur par défaut dans RC.4

6
répondu Günter Zöchbauer 2017-05-23 11:55:19

Router en angle 2 RC ne définit plus les méthodes isRouteActive et generate .

urlTree - renvoie l'arborescence d'url actuelle.

createUrlTree(commands: any[], segment?: RouteSegment) - applique un tableau de commandes à l'arbre d'url courant et crée un nouvel arbre d'url.

Essayez de suivre

<li 
[class.active]=
"router.urlTree.contains(router.createUrlTree(['/SignIn', this.routeSegment]))">

avis routeSegment : RouteSegment doit être injecté dans le constructeur du composant.

5
répondu tchelidze 2016-05-27 12:45:02

une instance de la classe Router est en fait un Observable et renvoie le chemin courant à chaque fois qu'il change. C'est comme ça que je le fais:

export class AppComponent implements OnInit { 

currentUrl : string;

constructor(private _router : Router){
    this.currentUrl = ''
}

ngOnInit() {
    this._router.subscribe(
        currentUrl => this.currentUrl = currentUrl,
        error => console.log(error)
    );
}

isCurrentRoute(route : string) : boolean {
    return this.currentUrl === route;
 } 
}

et puis dans mon HTML:

<a [routerLink]="['Contact']" class="item" [class.active]="isCurrentRoute('contact')">Contact</a>
4
répondu Anees Dhansey 2016-05-15 17:50:21

Une Autre Solution. Beaucoup plus facile dans le routeur angulaire V3 Alpha. en injectant le routeur

import {Router} from "@angular/router";

export class AppComponent{

    constructor(private router : Router){}

    routeIsActive(routePath: string) {
        return this.router.url == routePath;
    }
}

utilisation

<div *ngIf="routeIsActive('/')"> My content </div>
4
répondu shakee93 2016-06-25 11:17:28

dans Angular2 RC2 vous pouvez utiliser cette simple implémentation""

<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>

cela va ajouter la classe active à l'élément avec url appariée, lire la suite de il ici

4
répondu Khaled Al-Ansari 2016-07-10 09:44:43

ci-dessous sont les réponses à cette question pour toutes les versions de 2 versions RC Angular sorties jusqu'à date:

RC4 et RC3 :

pour l'application de la classe au lien ou à l'ancêtre du lien:

<li routerLinkActive="active"><a [routerLink]="['/home']">Home</a></li>

/home doit être l'URL et pas le nom de la route depuis le nom de la propriété n'existe plus sur la Route Objet de Routeur v3.

plus d'information sur routerLinkActive directive à ce link .

pour l'application de la classe à tout div basé sur la route actuelle:

  • injecter routeur dans le constructeur du composant.
  • de l'Utilisateur du routeur.url pour la comparaison.

E. g

<nav [class.transparent]="router.url==('/home')">
</nav>

RC2 et RC1 :

utiliser une combinaison de routeur.isRouteActive et la classe.*. E. g appliquer la classe active en fonction de la Route D'origine.

le nom et l'url peuvent tous deux être passés dans le routeur.générer.

 <li [class.active]="router.isRouteActive(router.generate(['Home']))">
    <a [routerLink]="['Home']" >Home</a>
</li>
4
répondu Inderdeep Singh 2016-07-15 10:15:27

utiliser routerLinkActive est bon dans les cas simples, quand il y a un lien et vous voulez appliquer quelques classes. Mais dans les cas plus complexes où vous n'avez pas de routerLink ou où vous avez besoin de quelque chose de plus, vous pouvez créer et utiliser un pipe :

@Pipe({
    name: "isRouteActive",
    pure: false
})
export class IsRouteActivePipe implements PipeTransform {

    constructor(private router: Router,
                private activatedRoute: ActivatedRoute) {
    }

    transform(route: any[], options?: { queryParams?: any[], fragment?: any, exact?: boolean }) {
        if (!options) options = {};
        if (options.exact === undefined) options.exact = true;

        const currentUrlTree = this.router.parseUrl(this.router.url);
        const urlTree = this.router.createUrlTree(route, {
            relativeTo: this.activatedRoute,
            queryParams: options.queryParams,
            fragment: options.fragment
        });
        return containsTree(currentUrlTree, urlTree, options.exact);
    }
}

puis:

<div *ngIf="['/some-route'] | isRouteActive">...</div>

et n'oubliez pas d'inclure dans la tuyauterie tuyaux dépendances ;)

4
répondu pleerock 2016-07-16 18:42:04

comme mentionné dans l'un des commentaires de la réponse acceptée, la directive routerLinkActive peut également s'appliquer à un contenant de la véritable étiquette <a> .

donc par exemple avec les onglets de bootstraps Twitter où la classe active doit être appliquée à la balise <li> qui contient le lien:

<ul class="nav nav-tabs">
    <li role="presentation" routerLinkActive="active">
        <a routerLink="./location">Location</a>
    </li>
    <li role="presentation" routerLinkActive="active">
        <a routerLink="./execution">Execution</a>
    </li>
</ul>

plutôt chouette ! Je suppose que la directive inspecte le contenu de l'étiquette et cherche une Étiquette <a> avec la directive routerLink .

4
répondu Pierre Henry 2016-11-03 15:24:38

pour la version angulaire 4+, vous n'avez pas besoin d'utiliser une solution complexe. Vous pouvez simplement utiliser [routerLinkActive]="'is-active'" .

pour un exemple avec le lien nav bootstrap 4:

    <ul class="navbar-nav mr-auto">
      <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 class="nav-link " routerLink="/contact-us">Contact</a>
      </li>
    </ul>
4
répondu asmmahmud 2017-10-12 17:26:49

juste pensé que je voudrais ajouter dans un exemple qui n'utilise pas de dactylogramme:

<input type="hidden" [routerLink]="'home'" routerLinkActive #home="routerLinkActive" />
<section *ngIf="home.isActive"></section>

la variable routerLinkActive est liée à une variable modèle et réutilisée au besoin. Malheureusement, la seule réserve est que vous ne pouvez pas avoir tout cela sur l'élément <section> comme #home doit être résolu avant à l'analyseur frappant <section> .

2
répondu Zze 2018-02-21 10:03:51

je cherchais un moyen d'utiliser un nav de style Bootstrap Twitter avec Angular2, mais j'ai eu du mal à obtenir la classe active appliquée à l'élément parent du lien sélectionné. Trouvé que la solution de @alex-correia-santos fonctionne parfaitement!

le composant contenant vos onglets doit importer le routeur et le définir dans son constructeur avant que vous puissiez faire les appels nécessaires.

Voici une version simplifiée de mon implémentation...

import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {HomeComponent} from './home.component';
import {LoginComponent} from './login.component';
import {FeedComponent} from './feed.component';

@Component({
  selector: 'my-app',
  template: `
    <ul class="nav nav-tabs">
      <li [class.active]="_r.isRouteActive(_r.generate(['Home']))">
        <a [routerLink]="['Home']">Home</a>
      </li>
      <li [class.active]="_r.isRouteActive(_r.generate(['Login']))">
        <a [routerLink]="['Login']">Sign In</a>
      </li>
      <li [class.active]="_r.isRouteActive(_r.generate(['Feed']))">
        <a [routerLink]="['Feed']">Feed</a>
      </li>
    </ul>`,
  styleUrls: ['app/app.component.css'],
  directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
  { path:'/', component:HomeComponent, name:'Home', useAsDefault:true },
  { path:'/login', component:LoginComponent, name:'Login' },
  { path:'/feed', component:FeedComponent, name:'Feed' }
])
export class AppComponent {
  title = 'My App';
  constructor( private _r:Router ){}
}
1
répondu Ben Thielker 2016-04-13 18:25:40

disons que vous voulez ajouter CSS à mon état/onglet actif. Utilisez routerLinkActive pour activer votre lien de routage.

note:" actif "est mon nom de classe ici

<style>
   .active{
       color:blue;
     }
</style>

  <a routerLink="/home" [routerLinkActive]="['active']">Home</a>
  <a routerLink="/about" [routerLinkActive]="['active']">About</a>
  <a routerLink="/contact" [routerLinkActive]="['active']">Contact</a>
1
répondu UniCoder 2017-06-12 13:52:10

j'utilise le routeur angulaire ^3.4.7 et j'ai encore des problèmes avec la directive routerLinkActive .

cela ne fonctionne pas si vous avez plusieurs liens avec la même url plus il ne semble pas se rafraîchir tout le temps.

inspiré par @tomaszbak réponse j'ai créé un petit composant pour faire le travail

0
répondu RPDeshaies 2017-02-16 20:13:33

solution Simple pour les utilisateurs angulaires 5 est, il suffit d'ajouter routerLinkActive à l'article de la liste.

La directive

a routerLinkActive est associée à une route au moyen de la directive routerLink .

il prend comme entrée un tableau de classes qu'il ajoutera à l'élément auquel il est attaché si sa route est actuellement active, comme ceci:

<li class="nav-item"
    [routerLinkActive]="['active']">
  <a class="nav-link"
     [routerLink]="['home']">Home
  </a>
</li>

ce qui précède ajoutera une classe d'active à l'étiquette d'ancrage si nous regardons actuellement la maison de l'itinéraire.

Demo

0
répondu Prasanth Jaya 2018-04-17 10:19:44

Pur html template être comme

 <a [routerLink]="['/home']" routerLinkActive="active">Home</a>
 <a [routerLink]="['/about']" routerLinkActive="active">About us</a>
 <a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>
0
répondu Bellash 2018-06-22 13:05:06