HINWEIS: Hier gibt es viele verschiedene Antworten, und die meisten waren zu der einen oder anderen Zeit gültig. Tatsache ist, dass sich das, was funktioniert, mehrmals geändert hat, als das Angular Das Team hat seinen Router geändert. Die Router 3.0-Version, die in Angular schließlich the router sein wird, unterbricht viele dieser Lösungen, bietet jedoch eine sehr einfache eigene Lösung. 3 ist die bevorzugte Lösung, [routerLinkActive]
zu verwenden, wie in diese Antwort . Gezeigt.
Wie ermitteln Sie in einer Angular -Anwendung (aktuell in der Version 2.0.0-Beta.0, wie ich dies schreibe), welche Route derzeit aktiv ist?
Ich arbeite an einer App, die Bootstrap 4 verwendet, und ich benötige eine Möglichkeit, Navigationslinks/-schaltflächen als aktiv zu markieren, wenn die zugehörige Komponente in einem <router-output>
-Tag angezeigt wird.
Ich erkenne, dass ich den Status selbst beibehalten könnte, wenn auf eine der Schaltflächen geklickt wird, aber das würde nicht den Fall abdecken, dass mehrere Pfade zu derselben Route führen (z. B. ein Hauptnavigationsmenü sowie ein lokales Menü in der Hauptkomponente) ).
Anregungen oder Links wäre dankbar. Vielen Dank.
Mit dem neuen Angular-Router können Sie allen Ihren Links ein [routerLinkActive]="['your-class-name']"
-Attribut hinzufügen:
<a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a>
Oder das vereinfachte Nicht-Array-Format, wenn nur eine Klasse benötigt wird:
<a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a>
Weitere Informationen finden Sie in der schlecht dokumentierten routerLinkActive
-Direktive . (Ich habe das meistens durch Ausprobieren herausgefunden.)
UPDATE: Eine bessere Dokumentation für die routerLinkActive
-Direktive finden Sie jetzt hier . (Danke an @Victor Hugo Arango A. in den Kommentaren unten.)
Ich habe dies in einer anderen Frage beantwortet, aber ich glaube, es könnte auch für diese Frage relevant sein. Hier ist ein Link zur ursprünglichen Antwort: Angular 2: Wie kann eine aktive Route mit Parametern ermittelt werden?
Ich habe versucht, das einzustellen aktiv Klasse, ohne genau wissen zu müssen, was der aktuelle Standort ist (mit dem Routennamen). Die beste Lösung, die ich bisher hatte, ist die Verwendung der Funktion isRouteActive , die in der Klasse Router
verfügbar ist.
router.isRouteActive(instruction): Boolean
nimmt einen Parameter, der ein Routenobjekt Instruction
ist, und gibt true
oder false
zurück, unabhängig davon, ob diese Anweisung für die aktuelle Route gilt oder nicht. Sie können eine Route Instruction
erstellen, indem Sie Router
s generate (linkParams: Array) verwenden. LinkParams hat dasselbe Format wie ein Wert, der an eine routerLink - Direktive übergeben wird (z. B. router.isRouteActive(router.generate(['/User', { user: user.id }]))
).
So ist das RouteConfig könnte aussehen (Ich habe es ein bisschen angepasst, um die Verwendung von Params zu zeigen):
@RouteConfig([
{ path: '/', component: HomePage, name: 'Home' },
{ path: '/signin', component: SignInPage, name: 'SignIn' },
{ path: '/profile/:username/feed', component: FeedPage, name: 'ProfileFeed' },
])
Und das Aussicht würde so aussehen:
<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>
Dies war bisher meine bevorzugte Lösung für das Problem, es könnte auch für Sie hilfreich sein.
Ich habe ein Problem gelöst, auf das ich in link gestoßen bin, und finde heraus, dass es eine einfache Lösung für Ihre Frage gibt. Sie können stattdessen router-link-active
in Ihren Styles verwenden.
@Component({
styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
Kleine Verbesserung der Antwort auf @ alex-correia-santos basierend auf 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));
}
}
Und benutze es so:
<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>
Sie können die aktuelle Route überprüfen, indem Sie das Location
-Objekt in Ihre Steuerung einspeisen und die path()
überprüfen:
class MyController {
constructor(private location:Location) {}
... location.path(); ...
}
Sie müssen sicherstellen, dass Sie es zuerst importieren:
import {Location} from "angular2/router";
Sie können dann einen regulären Ausdruck verwenden, um den zurückgegebenen Pfad abzugleichen und festzustellen, welche Route aktiv ist. Beachten Sie, dass die Location
-Klasse einen normalisierten Pfad zurückgibt, unabhängig davon, welche LocationStrategy
Sie verwenden. Selbst wenn Sie die Variable HashLocationStragegy
verwenden, haben die zurückgegebenen Pfade immer noch die Form /foo/bar
nicht #/foo/bar
.
wie bestimmen Sie die derzeit aktive Route?
UPDATE: aktualisiert gemäß 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
}
Zur Markierung aktiver Routen kann routerLinkActive
verwendet werden
<a [routerLink]="/user" routerLinkActive="some class list">User</a>
Dies funktioniert auch bei anderen Elementen wie
<div routerLinkActive="some class list">
<a [routerLink]="/user">User</a>
</div>
Wenn Teilübereinstimmungen sollte auch markiert werden
routerLinkActive="some class list" [routerLinkActiveOptions]="{ exact: false }"
Soweit ich weiß, wird exact: false
in RC.4 der Standard sein
Im Moment verwende ich rc.4 mit bootstrap 4 und das funktioniert perfekt für mich:
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact:
true}">
<a class="nav-link" [routerLink]="['']">Home</a>
</li>
Dies funktioniert für URL:/home
Im Folgenden finden Sie die Methode, mit der Sie mithilfe von RouteData menuBar-Elemente abhängig von der aktuellen Route gestalten können:
RouteConfig enthält Daten mit Tab (aktuelle Route):
@RouteConfig([
{
path: '/home', name: 'Home', component: HomeComponent,
data: {activeTab: 'home'}, useAsDefault: true
}, {
path: '/jobs', name: 'Jobs', data: {activeTab: 'jobs'},
component: JobsComponent
}
])
Ein Stück Layout:
<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>
Klasse:
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;
}
}
Hier ist ein vollständiges Beispiel für das Hinzufügen eines aktiven Routenstils in der Angular-Version 2.0.0-rc.1
, der Null-Root-Pfade berücksichtigt (z. B. path: '/'
).
app.component.ts -> Routen
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>
Lösung für 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 definiert nicht mehr die Methoden isRouteActive
und generate
.
urlTree
- Gibt den aktuellen URL-Baum zurück.
createUrlTree(commands: any[], segment?: RouteSegment)
- Wendet ein Array von Befehlen auf die aktuelle URL-Struktur an und erstellt eine neue URL-Struktur.
Versuchen Sie folgendes
<li
[class.active]=
"router.urlTree.contains(router.createUrlTree(['/SignIn', this.routeSegment]))">
notice, routeSegment : RouteSegment
muss in den Konstruktor der Komponente eingefügt werden.
Die Verwendung von routerLinkActive
ist in einfachen Fällen sinnvoll, wenn ein Link vorhanden ist und Sie einige Klassen anwenden möchten. In komplexeren Fällen, in denen Sie möglicherweise keinen RouterLink haben oder wenn Sie etwas mehr benötigen, können Sie ein pipe erstellen und verwenden:
@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);
}
}
dann:
<div *ngIf="['/some-route'] | isRouteActive">...</div>
und vergiss nicht, Pipes in die Abhängigkeiten der Pipes aufzunehmen;)
Eine Instanz der Routerklasse ist tatsächlich ein Observable und gibt bei jeder Änderung den aktuellen Pfad zurück. So mache ich es:
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;
}
}
Und dann in meinem HTML:
<a [routerLink]="['Contact']" class="item" [class.active]="isCurrentRoute('contact')">Contact</a>
Ein weiterer Workaround. Viel einfacher in Angular Router V3 Alpha. durch Einspritzen des Routers
import {Router} from "@angular/router";
export class AppComponent{
constructor(private router : Router){}
routeIsActive(routePath: string) {
return this.router.url == routePath;
}
}
verwendungszweck
<div *ngIf="routeIsActive('/')"> My content </div>
In Angular2 RC2 können Sie diese einfache Implementierung verwenden
<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
dadurch wird dem Element mit der übereinstimmenden URL die Klasse active
hinzugefügt. Weitere Informationen dazu hier
Hier finden Sie die Antworten auf diese Frage für alle bis heute veröffentlichten Versionen der Angular 2 RC-Versionen:
RC4 und RC3:
Für das Anwenden einer Klasse für einen Link oder eines Vorfahren von Link:
<li routerLinkActive="active"><a [routerLink]="['/home']">Home</a></li>
/home sollte die URL und nicht der Name der Route sein, da die Name-Eigenschaft für Route Object ab Router v3 nicht mehr vorhanden ist.
Weitere Informationen zur routerLinkActive-Direktive finden Sie unter link .
Für das Anwenden einer Klasse auf ein beliebiges Div basierend auf der aktuellen Route:
z.B
<nav [class.transparent]="router.url==('/home')">
</nav>
RC2 und RC1:
Verwenden Sie eine Kombination aus router.isRouteActive und der Klasse *. z. B. um eine aktive Klasse basierend auf der Home Route anzuwenden.
Name und URL können beide an router.generate übergeben werden.
<li [class.active]="router.isRouteActive(router.generate(['Home']))">
<a [routerLink]="['Home']" >Home</a>
</li>
Für Angular Version 4+ müssen Sie keine komplexe Lösung verwenden. Sie können einfach [routerLinkActive]="'is-active'"
verwenden.
Für ein Beispiel mit 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>
Ich dachte nur, ich würde ein Beispiel hinzufügen, das kein TypeScript verwendet:
<input type="hidden" [routerLink]="'home'" routerLinkActive #home="routerLinkActive" />
<section *ngIf="home.isActive"></section>
Die Variable routerLinkActive
ist an eine Vorlagenvariable gebunden und wird bei Bedarf erneut verwendet. Leider besteht der einzige Nachteil darin, dass Sie nicht alles auf dem <section>
-Element haben können, da #home
aufgelöst werden muss vor bis der Parser auf <section>
trifft.
Wie in einem Kommentar der akzeptierten Antwort erwähnt, kann die routerLinkActive
-Direktive auch auf einen Container des eigentlichen <a>
-Tags angewendet werden.
So zum Beispiel mit Twitter-Bootstrap-Registerkarten wobei die aktive Klasse auf das <li>
-Tag angewendet werden sollte, das den Link enthält:
<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>
Ziemlich ordentlich! Ich nehme an, die Direktive prüft den Inhalt des Tags und sucht mit der routerLink
-Direktive nach einem <a>
-Tag.
Eine einfache Lösung für eckige 5 Benutzer ist, fügen Sie einfach routerLinkActive
zum Listenelement hinzu.
Eine routerLinkActive
-Direktive ist über eine routerLink
-Direktive einer Route zugeordnet.
Als Eingabe wird ein Array von Klassen verwendet, das zu dem Element hinzugefügt wird, an das es angehängt ist, wenn die Route derzeit aktiv ist.
<li class="nav-item"
[routerLinkActive]="['active']">
<a class="nav-link"
[routerLink]="['home']">Home
</a>
</li>
Das obige fügt dem Anker-Tag eine Klasse von aktiv hinzu, wenn wir gerade die Heimroute betrachten.
Ich habe nach einer Möglichkeit gesucht, ein Twitter Bootstrap-Style-Navi mit Angular2 zu verwenden, hatte jedoch Probleme, die active
-Klasse auf das übergeordnete Element des ausgewählten Links anzuwenden. Die Lösung von @ alex-correia-santos funktioniert einwandfrei!
Die Komponente, die Ihre Registerkarten enthält, muss den Router importieren und in seinem Konstruktor definieren, bevor Sie die erforderlichen Aufrufe durchführen können.
Hier ist eine vereinfachte Version meiner Implementierung ...
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 ){}
}
angenommen, Sie möchten CSS zu meinem aktiven Status/Tab hinzufügen. Verwenden Sie routerLinkActive , um Ihren Routing-Link zu aktivieren.
note: "active" ist mein Klassenname hier
<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>
Ab Angular 8 funktioniert Folgendes:
<li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
<a [routerLink]="['/']">Home</a>
</li>
{ exact: true }
stellt sicher, dass es mit der URL übereinstimmt.
beginnen Sie mit dem Importieren von RouterLinkActive in Ihre .ts
{RouterLinkActive} von '@ angle/router' importieren;
Verwenden Sie nun RouterLinkActive in Ihrem HTML-Code
<span class="" routerLink ="/some_path" routerLinkActive="class_Name">Value</span></a>
geben Sie der Klasse "class_Name" ein paar css an, da diese Klasse beim Überprüfen aktiv ist/angeklickt wird.
Reine HTML-Vorlage sein
<a [routerLink]="['/home']" routerLinkActive="active">Home</a>
<a [routerLink]="['/about']" routerLinkActive="active">About us</a>
<a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>
Und in der neuesten Version von Angular können Sie einfach router.isActive(routeNameAsString)
überprüfen. Beispiel siehe folgendes Beispiel:
<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>
Und stellen Sie sicher, dass Sie das Injizieren des Routers in Ihre Komponente nicht vergessen.
Ich verwende den kantigen Router ^3.4.7
und habe immer noch Probleme mit der routerLinkActive
-Direktive.
Es funktioniert nicht, wenn Sie mehrere Links mit derselben URL haben, und es scheint nicht, dass es ständig aktualisiert wird.
Inspiriert von der Antwort von @tomaszbak habe ich eine kleine Komponente erstellt, um die Arbeit zu erledigen