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é plusieurs fois, l'équipe angulaire ayant changé de routeur. La version 3.0 qui sera finalement le routeur dans Angular casse beaucoup de ces solutions, mais offre une solution très simple. A partir de RC.3, la solution recommandée consiste à utiliser [routerLinkActive]
comme indiqué dans cette réponse. .
Dans une application Angular (actuelle dans la version 2.0.0-beta.0 au moment où j'écris ceci), comment déterminez-vous quel est l'itinéraire actuellement actif?
Je travaille sur une application qui utilise Bootstrap 4 et j'ai besoin d'un moyen de marquer les liens/boutons de navigation comme étant actifs lorsque leur composant associé est affiché dans une balise <router-output>
.
Je me rends compte que je pourrais conserver moi-même l'état lorsque l'un des boutons est cliqué, mais cela ne couvrirait pas le cas de plusieurs chemins dans le même itinéraire (disons un menu de navigation principal ainsi qu'un menu local dans le composant principal ).
Toute suggestion ou lien serait apprécié. Merci.
Avec le nouveau routeur Angular , vous pouvez ajouter un attribut [routerLinkActive]="['your-class-name']"
à tous vos liens:
<a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a>
Ou le format simplifié non-tableau si une seule classe est nécessaire:
<a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a>
Voir la directive mal documentée routerLinkActive
pour plus d'informations. (J'ai surtout compris cela par essais et erreurs.)
UPDATE: Il est maintenant possible de trouver une meilleure documentation pour la directive routerLinkActive
here . (Merci à @Victor Hugo Arango A. dans les commentaires ci-dessous.)
J'ai répondu à cela dans une autre question, mais je pense que cela pourrait également s'appliquer à celle-ci. Voici un lien vers la réponse originale: Angular 2: Comment déterminer un itinéraire actif avec des paramètres?
J'ai essayé de régler le actif classe sans avoir à savoir exactement quelle est la position actuelle (en utilisant le nom de la route). Pour l'instant, la meilleure solution consiste à utiliser la fonction isRouteActive disponible dans la classe Router
.
router.isRouteActive(instruction): Boolean
prend un paramètre qui est un objet route Instruction
et renvoie true
ou false
si cette instruction est vraie ou non pour la route en cours. Vous pouvez générer une route Instruction
en utilisant Router
's generate (linkParams: Array) . LinkParams suit exactement le même format qu’une valeur passée dans une directive routerLink (par exemple, router.isRouteActive(router.generate(['/User', { user: user.id }]))
).
Voici comment RouteConfig pourrait ressembler (Je l'ai un peu modifié pour montrer l'utilisation de params):
@RouteConfig([
{ path: '/', component: HomePage, name: 'Home' },
{ path: '/signin', component: SignInPage, name: 'SignIn' },
{ path: '/profile/:username/feed', component: FeedPage, name: 'ProfileFeed' },
])
Et le Vue 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, cela pourrait également vous être utile.
J'ai résolu un problème rencontré dans ce link et je découvre qu'il existe une solution simple à votre question. Vous pouvez utiliser router-link-active
à la place dans vos styles.
@Component({
styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
Petite amélioration de la réponse @ 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 utilisez-le 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>
Vous pouvez vérifier l'itinéraire actuel en injectant l'objet Location
dans votre contrôleur et en vérifiant le path()
, comme suit:
class MyController {
constructor(private location:Location) {}
... location.path(); ...
}
Vous devrez d'abord l'importer:
import {Location} from "angular2/router";
Vous pouvez ensuite utiliser une expression régulière pour établir une correspondance avec le chemin renvoyé afin de voir quel itinéraire est actif. Notez que la classe Location
renvoie un chemin normalisé quel que soit le LocationStrategy
que vous utilisez. Ainsi, même si vous utilisez la variable HashLocationStragegy
, les chemins renvoyés seront toujours de la forme /foo/bar
pas #/foo/bar
comment déterminez-vous l'itinéraire actuel?
UPDATE: mis à 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
}
Pour marquer des itinéraires actifs, routerLinkActive
peut être utilisé
<a [routerLink]="/user" routerLinkActive="some class list">User</a>
Cela fonctionne également sur d'autres éléments comme
<div routerLinkActive="some class list">
<a [routerLink]="/user">User</a>
</div>
Si les correspondances partielles doivent également être marquées, utilisez
routerLinkActive="some class list" [routerLinkActiveOptions]="{ exact: false }"
Autant que je sache, exact: false
va être la valeur par défaut dans RC.4
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>
Cela fonctionnera pour url:/home
Ci-dessous, la méthode utilisant RouteData pour styler les éléments de menuBar en fonction de l'itinéraire actuel:
RouteConfig inclut des données avec onglet (itinéraire actuel):
@RouteConfig([
{
path: '/home', name: 'Home', component: HomeComponent,
data: {activeTab: 'home'}, useAsDefault: true
}, {
path: '/jobs', name: 'Jobs', data: {activeTab: 'jobs'},
component: JobsComponent
}
])
Un morceau de 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;
}
}
Voici un exemple complet d'ajout de style de route active dans la version angulaire 2.0.0-rc.1
qui prend en compte les chemins racine nuls (par exemple path: '/'
)
app.component.ts -> Itinéraires
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.component.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>
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);
}
Router
in Angular 2 RC ne définit plus les méthodes isRouteActive
et generate
.
urlTree
- Retourne l’arborescence actuelle.
createUrlTree(commands: any[], segment?: RouteSegment)
- Applique un tableau de commandes à l’arborescence actuelle et crée une nouvelle arborescence.
Essayez de suivre
<li
[class.active]=
"router.urlTree.contains(router.createUrlTree(['/SignIn', this.routeSegment]))">
notice, routeSegment : RouteSegment
doit être injecté dans le constructeur du composant.
Utiliser routerLinkActive
est bon dans les cas simples, quand il y a un lien et que vous voulez appliquer des classes. Mais dans les cas plus complexes où vous n’avez peut-être pas de routeur (ou un lien supplémentaire), 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 pipe dans les dépendances de pipes;)
Une instance de la classe Router est en réalité un observable et renvoie le chemin actuel à chaque changement. Voici comment 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>
Une autre solution de contournement. Beaucoup plus facile dans Angular Router V3 Alpha. en injectant un routeur
import {Router} from "@angular/router";
export class AppComponent{
constructor(private router : Router){}
routeIsActive(routePath: string) {
return this.router.url == routePath;
}
}
usage
<div *ngIf="routeIsActive('/')"> My content </div>
Dans Angular2 RC2, vous pouvez utiliser cette implémentation simple
<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
cela ajoutera la classe active
à l'élément avec l'URL correspondante, en savoir plus à ce sujet ici
Vous trouverez ci-dessous les réponses à cette question pour toutes les versions des versions d'Angular 2 RC publiées jusqu'à ce jour:
RC4 et RC3:
Pour appliquer une classe à un lien ou un ancêtre de lien:
<li routerLinkActive="active"><a [routerLink]="['/home']">Home</a></li>
/home doit être l'URL et non le nom de la route car la propriété name n'existe plus sur l'objet Route à partir du routeur v3.
Plus d'informations sur la directive routerLinkActive à cette lien .
Pour appliquer une classe à une division en fonction de l’itinéraire actuel:
par exemple
<nav [class.transparent]="router.url==('/home')">
</nav>
RC2 et RC1:
Utilisez une combinaison de router.isRouteActive et class. *. par exemple, appliquer une classe active basée sur l'itinéraire local.
Nom et URL peuvent être tous deux passés dans router.generate.
<li [class.active]="router.isRouteActive(router.generate(['Home']))">
<a [routerLink]="['Home']" >Home</a>
</li>
Pour Angular version 4+, vous n’avez besoin d’aucune solution complexe. Vous pouvez simplement utiliser [routerLinkActive]="'is-active'"
.
Pour un exemple avec bootstrap 4 nav link:
<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>
Je pensais juste que j'ajouterais un exemple qui n'utilise aucun TypeScript:
<input type="hidden" [routerLink]="'home'" routerLinkActive #home="routerLinkActive" />
<section *ngIf="home.isActive"></section>
La variable routerLinkActive
est liée à une variable de modèle, puis réutilisée selon les besoins. Malheureusement, le seul inconvénient est que vous ne pouvez pas avoir tout cela sur l'élément <section>
car #home
doit être résolu avant à l'analyseur qui clique sur <section>
.
Comme indiqué dans l'un des commentaires de la réponse acceptée, la directive routerLinkActive
peut également être appliquée à un conteneur de la balise <a>
réelle.
Ainsi par exemple avec les onglets Twitter Bootstrap 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>
Génial ! Je suppose que la directive inspecte le contenu de la balise et recherche une balise <a>
avec la directive routerLink
.
La solution simple pour les utilisateurs angulaires 5 consiste simplement à ajouter routerLinkActive
à l’élément de la liste.
Une directive routerLinkActive
est associée à une route via une directive routerLink
.
Il prend en 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'actif à la balise d'ancrage si nous visualisons actuellement l'itinéraire de départ.
Je cherchais un moyen d'utiliser une navigation de style Twitter Bootstrap avec Angular2, mais je ne pouvais pas appliquer la classe active
à l'élément parent du lien sélectionné. Constaté 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 de pouvoir effectuer 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 ){}
}
supposons que vous souhaitiez ajouter du CSS à mon état/onglet actif. Utilisez routerLinkActive pour activer votre lien de routage.
note: 'actif' est le nom de ma 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>
À partir de Angular 8, cela fonctionne:
<li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
<a [routerLink]="['/']">Home</a>
</li>
{ exact: true }
s'assure qu'il correspond à l'URL.
commencez par importer RouterLinkActive dans votre fichier .ts
importer {RouterLinkActive} depuis '@ angular/router';
Maintenant, utilisez RouterLinkActive dans votre code HTML
<span class="" routerLink ="/some_path" routerLinkActive="class_Name">Value</span></a>
fournissez quelques css à la classe "nom_classe", car lorsque ce lien sera actif/cliqué, vous trouverez cette classe sur la durée de l'inspection.
Modèle html pur soit comme
<a [routerLink]="['/home']" routerLinkActive="active">Home</a>
<a [routerLink]="['/about']" routerLinkActive="active">About us</a>
<a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>
Et dans la dernière version de angular, vous pouvez simplement vérifier router.isActive(routeNameAsString)
. Par exemple, voir l'exemple ci-dessous:
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item" [class.active] = "router.isActive('/dashboard')">
<a class="nav-link" href="#">داشبورد <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item" [class.active] = "router.isActive(route.path)" *ngFor="let route of (routes$ | async)">
<a class="nav-link" href="javascript:void(0)" *ngIf="route.childRoutes && route.childRoutes.length > 0"
[matMenuTriggerFor]="menu">{{route.name}}</a>
<a class="nav-link" href="{{route.path}}"
*ngIf="!route.childRoutes || route.childRoutes.length === 0">{{route.name}}</a>
<mat-menu #menu="matMenu">
<span *ngIf="route.childRoutes && route.childRoutes.length > 0">
<a *ngFor="let child of route.childRoutes" class="nav-link" href="{{route.path + child.path}}"
mat-menu-item>{{child.name}}</a>
</span>
</mat-menu>
</li>
</ul>
<span class="navbar-text mr-auto">
<small>سلام</small> {{ (currentUser$ | async) ? (currentUser$ | async).firstName : 'کاربر' }}
{{ (currentUser$ | async) ? (currentUser$ | async).lastName : 'میهمان' }}
</span>
</div>
Et assurez-vous de ne pas oublier d’injecter un routeur dans votre composant.
J'utilise un routeur angulaire ^3.4.7
et j'ai toujours des problèmes avec la directive routerLinkActive
.
Cela ne fonctionne pas si vous avez plusieurs liens avec la même URL, plus cela ne semble pas rafraîchir tout le temps.
Inspiré par @tomaszbak answer, j'ai créé un petit composant pour faire le travail