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.
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.)
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.
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 {
}
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>
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
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
}
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;
}
}
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>
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);
}
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
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
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.
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>
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>
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
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>
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 ;)
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
.
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>
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>
.
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 ){}
}
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>
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
solution Simple pour les utilisateurs angulaires 5 est, il suffit d'ajouter routerLinkActive
à l'article de la liste.
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.
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>