wake-up-neo.net

Wie bestimmen Sie in Angular die aktive Route?

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.

232
Michael Oryl

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

283
jessepinho

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

65
Alex Santos

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 {
}
33
Quy Tang

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

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.

28
Jason Teplitz

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
}

Mehr sehen...

16
Ankit Singh

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

8

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

7
Artem Zinoviev

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;
  }
}
6
Ivan

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>
6
Levi Fuller

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);
}
6
lukaville

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. 

5
tchelidze

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

4
pleerock

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>
4
Anees Dhansey

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

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

4

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: 

  • Fügen Sie den Router in den Konstruktor der Komponente ein. 
  • Benutzer router.url zum Vergleich. 

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>
4
Inderdeep Singh

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

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.

3
Zze

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.

3
Pierre Henry

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.

 Demo

1
Prasanth Jaya

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 ){}
}
1
Ben Thielker

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

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.

0
John Kennedy

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.

0
T. Shashwat

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

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.

0
ConductedClever

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

0
RPDeshaies