W Angular, w jaki sposób określasz aktywną trasę?

311

UWAGA: Istnieje wiele różnych odpowiedzi, a większość z nich była poprawna w tym samym czasie. Faktem jest, że to, co działa, zmieniało się wiele razy, gdy zespół Angular zmienił swój router. Wersja Routera 3.0, która ostatecznie stanie się routerem w Angular, łamie wiele z tych rozwiązań, ale oferuje bardzo proste własne rozwiązanie. Począwszy od wersji RC.3, preferowanym rozwiązaniem jest użycie, [routerLinkActive]jak pokazano w tej odpowiedzi .

W aplikacji Angular (bieżącej w wersji 2.0.0-beta.0, gdy to piszę), w jaki sposób określasz, jaka jest obecnie aktywna trasa?

Pracuję nad aplikacją korzystającą z Bootstrap 4 i potrzebuję sposobu, aby oznaczyć łącza / przyciski nawigacyjne jako aktywne, gdy ich powiązany komponent jest wyświetlany w <router-output>znaczniku.

Zdaję sobie sprawę, że sam mógłbym utrzymać stan po kliknięciu jednego z przycisków, ale nie obejmowałoby to przypadku posiadania wielu ścieżek na tej samej trasie (powiedzmy główne menu nawigacyjne, a także menu lokalne w głównym komponencie ).

Wszelkie sugestie lub linki będą mile widziane. Dzięki.

Michael Oryl
źródło

Odpowiedzi:

354

Dzięki nowemu routerowi Angular możesz dodać [routerLinkActive]="['your-class-name']"atrybut do wszystkich swoich łączy:

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

Lub uproszczony format inny niż macierz, jeśli potrzebna jest tylko jedna klasa:

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

Lub jeszcze prostszy format, jeśli potrzebna jest tylko jedna klasa:

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

Aby uzyskać więcej informacji, zobacz źle udokumentowaną routerLinkActivedyrektywę . (W większości to rozgryzłem metodą prób i błędów).

AKTUALIZACJA: Lepszą dokumentację dla routerLinkActivedyrektywy można teraz znaleźć tutaj . (Dzięki @Victor Hugo Arango A. w komentarzach poniżej.)

jessepinho
źródło
4
Czy jest jakiś sposób, aby się aktywował, gdy dzieci na trasie są aktywne? Kod ma @inputopcje for, ale exact: falseaktywuje klasę, gdy aktywne jest również rodzeństwo bieżącej trasy.
Matej
1
@ GabrieleB-David Nie testowałem tego, ale zakładam, router.navigate()że zadziałałoby dobrze. routerLinkActivejest po prostu wskaźnikiem tego, czy ten link reprezentuje aktywną trasę.
jessepinho
7
W podanym przykładzie [routerLinkActive] jest dodawany do znacznika <a />, jednak można go również umieścić na innych elementach, jeśli klasa jest wymagana w innym miejscu. <ul> <li [routerLinkActive] = "['active']"> <a [routerLink]="[myRoute.Route]">
Oblivion2000
2
@jessepinho - Próbowałem - [routerLinkActive] = "'aktywny'" będzie działał tylko wtedy, gdy masz również [routerLink] w znaczniku a. Jeśli miałeś (click) = "navitageTo ('/ route')" zamiast [routerLink], a w tej funkcji wywołałeś this.router.navigate (route), nowy komponent się załaduje, ale twoja aktywna klasa CSS wygrała ' być stosowane. Próbuję zrobić coś innego w tej funkcji oprócz this.router.navigate (..).
Mickael Caruso
2
Przykład w oficjalnej dokumentacji może ci pomóc: angular.io/docs/ts/latest/api/router/index/...
Victor Hugo Arango A.
69

Odpowiedziałem na to w innym pytaniu, ale wydaje mi się, że to może mieć znaczenie również w tym przypadku. Oto link do oryginalnej odpowiedzi: Angular 2: Jak ustalić aktywną trasę za pomocą parametrów?

Próbowałem ustawić aktywną klasę, nie musząc dokładnie wiedzieć, jaka jest bieżąca lokalizacja (używając nazwy trasy) . Najlepszym rozwiązaniem do tej pory jest skorzystanie z funkcji isRouteActive dostępnej w Routerklasie.

router.isRouteActive(instruction): Booleanpobiera jeden parametr, który jest obiektem trasy Instructioni zwraca truelub falseczy ta instrukcja ma wartość true dla bieżącej trasy, czy nie. Można wygenerować trasę Instructionza pomocą Router„s generowanie (linkParams: Array) . LinkParams ma dokładnie ten sam format, co wartość przekazana do dyrektywy routerLink (np router.isRouteActive(router.generate(['/User', { user: user.id }])).).

Tak może wyglądać RouteConfig (trochę go poprawiłem, aby pokazać użycie parametrów) :

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

A View będzie wyglądać następująco:

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

To było moje preferowane rozwiązanie problemu do tej pory, może być również pomocne dla ciebie.

Alex Santos
źródło
1
Myślę, że to rozwiązanie jest lepsze niż zaakceptowane, ponieważ używa Angular API zamiast wyrażeń regularnych pasujących do ścieżki. To wciąż jest trochę brzydkie, byłoby miło po prostu móc to zrobić router.isRouteActive('Home').
Philip
2
Nikita Vlasenko
5
nie należy zapominać o wprowadzeniu Routerkonstruktora klasy
Nikity Vlasenko
2
W najnowszej wersji Angular 2 użyłem namezamiast asw obiekcie konfiguracji routera.
ComFreek
9
Można tego użyć zamiast tego w rc1:router.urlTree.contains(router.createUrlTree(['Home']))
František Žiačik
35

Rozwiązałem problem napotkany w tym linku i okazało się, że istnieje proste rozwiązanie dla twojego pytania. Możesz użyć router-link-activezamiast tego w swoich stylach.

@Component({
   styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
Quy Tang
źródło
2
Uważam, że powinna to być zaakceptowana odpowiedź. Router Angular2 doda to automatycznie dla Ciebie.
Gabu
2
niestety klasa ta dodaje <a>, a nie <li>
laifjei
niestety tak naprawdę nie działa dobrze. Mam jedno dynamicznie generowane menu, a router-link-activeklasa nie jest dodawana do aktywnego alub li. ale jest jedno miejsce, w którym używam bootstrap nav-tabsi działa tam.
Shri
33

Małe ulepszenie odpowiedzi @ Alex-Correia-Santos na podstawie 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));
  }
} 

I użyj tego w ten sposób:

<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>
tomaszbak
źródło
oraz styl w komponencie styles : [.active {background-color: aliceblue; } ]. +1 to działa
Pratik Kelwalkar
Świetne rozwiązanie, dzięki któremu możesz ustawić router jako prywatny.
Kelvin Dealca,
Jest to znacznie lepsze rozwiązanie i jest szczególnie przydatne dla nooba, który zapomina o drobiazgach, takich jak tworzenie konstruktora i przekazywanie routera! Całkowicie zasługujesz na czek.
metodolog
30

Możesz sprawdzić bieżącą trasę, wstrzykując Locationobiekt do kontrolera i sprawdzając path():

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

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

Najpierw musisz go zaimportować:

import {Location} from "angular2/router";

Następnie możesz użyć wyrażenia regularnego, aby dopasować do zwróconej ścieżki, aby zobaczyć, która trasa jest aktywna. Zauważ, że Locationklasa zwraca znormalizowaną ścieżkę niezależnie od tego LocationStrategy, którego używasz. Więc nawet jeśli korzystasz ze HashLocationStragegyzwróconych ścieżek, nadal będą miały formę /foo/bar nie #/foo/bar

Jason Teplitz
źródło
17

jak określić, która jest obecnie aktywna trasa?

AKTUALIZACJA: zaktualizowana zgodnie z 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
}

Zobacz więcej...

Ankit Singh
źródło
14

Aby oznaczyć aktywne trasy, routerLinkActivemożna użyć

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

Działa to również na inne elementy, takie jak

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

Jeśli częściowe mecze również powinny być oznaczone, użyj

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

O ile wiem, exact: falsebędzie to domyślna wersja RC.4

Günter Zöchbauer
źródło
11

Obecnie używam rc.4 z bootstrap 4 i ten działa idealnie dla mnie:

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

To zadziała dla adresu url: / home

Artem Zinowiew
źródło
Jaki jest cel tej opcji? Czy to sprawia, że ​​nie pasuje do podścieżek takich jak /home/whatever?
Michael Oryl,
tak, exactznaczy, że trasa będzie miała tę samą nazwę. Jest to wymagane, jeśli planujesz używać go z narzędziami takimi jak Twitter Bootstrap. Obsługuje już stan aktywnego łącza i bez exactopcji nie będzie działać. (nie jestem pewien, jak to działa w rdzeniu, próbowałem i działa dla mnie)
Artem Zinoviev
7

Poniżej znajduje się metoda wykorzystująca RouteData do stylizacji elementów menuBar w zależności od bieżącej trasy:

RouteConfig zawiera dane z zakładką (aktualna trasa):

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

Kawałek układu:

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

Klasa:

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;
  }
}
Ivan
źródło
7

Pomyślałem, że dodam w przykładzie, który nie używa żadnego maszynopisu:

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

routerLinkActiveZmienna jest zobowiązany do zmiennej szablonu, a następnie ponownie wykorzystywane zgodnie z wymaganiami. Niestety jedynym zastrzeżeniem jest to, że nie możesz mieć tego wszystkiego na <section>elemencie, ponieważ #homenależy to rozwiązać przed uderzeniem parsera <section>.

Zze
źródło
Idealne rozwiązanie do zastosowania warunków na aktywnych trasach. Gdzie @ kątowy / router lub inaczej nie działał.
Rohit Parte
Wow, to jest bardzo pomocne. Dzięki!
Julian
6

Routerw Angular 2 RC już nie definiuje isRouteActivei nie generatestosuje metod.

urlTree - Zwraca bieżące drzewo adresu URL.

createUrlTree(commands: any[], segment?: RouteSegment) - Stosuje tablicę poleceń do bieżącego drzewa adresów URL i tworzy nowe drzewo adresów URL.

Spróbuj śledzić

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

Uwaga, routeSegment : RouteSegmentmusi zostać wstrzyknięty do konstruktora komponentu.

tchelidze
źródło
6

Oto kompletny przykład dodawania aktywnego stylu trasy w wersji Angular, 2.0.0-rc.1która uwzględnia zerowe ścieżki główne (np. path: '/')

app.component.ts -> Trasy

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>
Levi Fuller
źródło
6

Rozwiązanie dla 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);
}
Lukaville
źródło
5

Od wersji Angular 8 działa to:

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

{ exact: true } zapewnia, że ​​pasuje do adresu URL.

codejockie
źródło
5

w 2020 r., jeśli chcesz ustawić klasę aktywną na elemencie, który nie ma [routerLink] - możesz po prostu:

<a
  (click)="bookmarks()"
  [class.active]="router.isActive('/string/path/'+you+'/need', false)" // <== you need this one. second argument 'false' - exact: true/false
  routerLinkActive="active"
  [routerLinkActiveOptions]="{ exact: true }"
>
  bookmarks
</a>
Kurkov Igor
źródło
Dzięki, Igor. To najlepsze rozwiązanie.
Dmitry Grinko
Dziękujemy za opinię :)
Kurkov Igor
4

Kolejne obejście. Znacznie łatwiej w Angular Router V3 Alpha. przez wstrzyknięcie routera

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

export class AppComponent{

    constructor(private router : Router){}

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

stosowanie

<div *ngIf="routeIsActive('/')"> My content </div>
shakee93
źródło
zaraz po zaimportowaniu otrzymuję właściwość Nie mogę odczytać właściwości „isSkipSelf” o błędzie zerowym. jakieś pomysły?
atsituab
4

W Angular2 RC2 możesz użyć tej prostej implementacji

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

to doda klasę activedo elementu o dopasowanym adresie URL, czytaj więcej o tym tutaj

Khaled Al-Ansari
źródło
4

Poniżej znajdują się odpowiedzi na to pytanie dla wszystkich wersji Angular 2 RC wydanych do dnia:

RC4 i RC3 :

Aby zastosować klasę do linku lub przodka linku:

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

/ home powinien być adresem URL, a nie nazwą trasy, ponieważ właściwość name nie istnieje już w obiekcie trasy od routera v3.

Więcej informacji o dyrektywie routerLinkActive pod tym linkiem .

Aby zastosować klasę do dowolnego div na podstawie bieżącej trasy:

  • Wstaw router do konstruktora komponentu.
  • Użytkownik router.url do porównania.

na przykład

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

RC2 i RC1 :

Użyj kombinacji router.isRouteActive i klasy. *. np. zastosować klasę aktywną na podstawie trasy domowej.

Nazwę i adres URL można przekazać do router.generate.

 <li [class.active]="router.isRouteActive(router.generate(['Home']))">
    <a [routerLink]="['Home']" >Home</a>
</li>
Inderdeep Singh
źródło
4

Używanie routerLinkActivejest dobre w prostych przypadkach, gdy istnieje link i chcesz zastosować niektóre klasy. Ale w bardziej złożonych przypadkach, w których możesz nie mieć routera Link lub gdy potrzebujesz czegoś więcej, możesz utworzyć i użyć potoku :

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

następnie:

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

i nie zapomnij dołączyć rury do zależności rur;)

pleerock
źródło
Fajny pomysł, ale w angular2.0.0rc3 zmieniam this.router.isRouteActive ... na this._location.path () i umieszczam na górze: import {Location} z '@ angular / common';
Kamil Kiełczewski
2
Wydaje się, że czegoś brakuje w kodzie. Gdzie jest containsTreezdefiniowane?
Øystein Amundsen
4

W przypadku wersji Angular 4+ nie musisz używać żadnego złożonego rozwiązania. Możesz po prostu użyć [routerLinkActive]="'is-active'".

Na przykład z linkiem nawigacyjnym 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>
asmmahmud
źródło
3

Instancja klasy Router jest w rzeczywistości Obserowalna i zwraca bieżącą ścieżkę za każdym razem, gdy się zmienia. Tak to robię:

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

A potem w moim HTML:

<a [routerLink]="['Contact']" class="item" [class.active]="isCurrentRoute('contact')">Contact</a>
Anees Dhansey
źródło
1
Subskrypcja nie jest dostępna w instancji routera.
Shivang Gupta
3

Jak wspomniano w jednym z komentarzy do zaakceptowanej odpowiedzi, routerLinkActivedyrektywę można również zastosować do kontenera rzeczywistego <a>znacznika.

Na przykład z kartami Bootstrap na Twitterze, gdzie aktywna klasa powinna być zastosowana do <li>tagu zawierającego link:

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

Całkiem schludnie! Podejrzewam, że dyrektywa sprawdza zawartość tagu i szuka <a>tagu z routerLinkdyrektywą.

Pierre Henry
źródło
2

Prostym rozwiązaniem dla 5 użytkowników kątowych jest, po prostu dodaj routerLinkActivedo elementu listy.

routerLinkActiveDyrektywa związana jest z trasy przezrouterLink dyrektywy.

Jako dane wejściowe przyjmuje tablicę klas, które doda do elementu, do którego jest dołączony, jeśli jego trasa jest obecnie aktywna, na przykład:

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

Powyższe doda klasę aktywną do tagu zakotwiczenia, jeśli aktualnie oglądamy trasę główną.

Próbny

Prasanth Jaya
źródło
2

A w najnowszej wersji kątowej możesz po prostu zrobić sprawdzenie router.isActive(routeNameAsString). Na przykład patrz przykład poniżej:

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

I upewnij się, że nie zapominasz wstrzykiwać routera do swojego komponentu.

ConductClever
źródło
1

Szukałem sposobu korzystania z nawigacji w stylu Bootstrap na Twitterze w Angular2, ale miałem problem z uzyskaniem active zastosowaniem klasy do elementu nadrzędnego wybranego łącza. Okazało się, że rozwiązanie @ alex-correia-santos działa idealnie!

Składnik zawierający zakładki musi zaimportować router i zdefiniować go w swoim konstruktorze, zanim będzie można wykonać niezbędne wywołania.

Oto uproszczona wersja mojej implementacji ...

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 ){}
}
Ben Thielker
źródło
1

powiedzmy, że chcesz dodać CSS do mojego aktywnego stanu / karty. Użyj routerLinkActive, aby aktywować łącze do routingu.

uwaga: „aktywne” to tutaj nazwa mojej klasy

<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>
UniCoder
źródło
0

Używam routera kątowego ^3.4.7i nadal mam problemy z routerLinkActivedyrektywą.

To nie działa, jeśli masz wiele linków z tym samym adresem URL i wydaje się, że nie odświeżają się cały czas.

Zainspirowany odpowiedzią @tomaszbak stworzyłem mały komponent do wykonania zadania

RPDeshaies
źródło
0

Czysty szablon HTML powinien być jak

 <a [routerLink]="['/home']" routerLinkActive="active">Home</a>
 <a [routerLink]="['/about']" routerLinkActive="active">About us</a>
 <a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>
Bellash
źródło
0

zacznij od importowania RouterLinkActive do .ts

import {RouterLinkActive} z '@ angular / router';

Teraz użyj RouterLinkActive w swoim HTML

<span class="" routerLink ="/some_path" routerLinkActive="class_Name">Value</span></a>

podaj trochę css do klasy „class_Name”, ponieważ kiedy ten link będzie aktywny / kliknięty, znajdziesz klasę na rozpiętości podczas inspekcji.

T. Shashwat
źródło
0

Programowym sposobem byłoby zrobienie tego w samym komponencie. Zmagałem się z tym problemem przez trzy tygodnie, ale zrezygnowałem z kątowych dokumentów i przeczytałem rzeczywisty kod, który sprawił, że routerlinkactive działał, i to o najlepszych dokumentach, jakie mogę znaleźć.

    import {
  Component,AfterContentInit,OnDestroy, ViewChild,OnInit, ViewChildren, AfterViewInit, ElementRef, Renderer2, QueryList,NgZone,ApplicationRef
}
  from '@angular/core';
  import { Location } from '@angular/common';

import { Subscription } from 'rxjs';
import {
  ActivatedRoute,ResolveStart,Event, Router,RouterEvent, NavigationEnd, UrlSegment
} from '@angular/router';
import { Observable } from "rxjs";
import * as $ from 'jquery';
import { pairwise, map } from 'rxjs/operators';
import { filter } from 'rxjs/operators';
import {PageHandleService} from '../pageHandling.service'
@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})




export class HeaderComponent implements AfterContentInit,AfterViewInit,OnInit,OnDestroy{

    public previousUrl: any;
    private subscription: Subscription;


      @ViewChild("superclass", { static: false } as any) superclass: ElementRef;
      @ViewChildren("megaclass") megaclass: QueryList<ElementRef>;


  constructor( private element: ElementRef, private renderer: Renderer2, private router: Router, private activatedRoute: ActivatedRoute, private location: Location, private pageHandleService: PageHandleService){
    this.subscription = router.events.subscribe((s: Event) => {
      if (s instanceof NavigationEnd) {
        this.update();
      }
    });


  }


  ngOnInit(){

  }


  ngAfterViewInit() {
  }

  ngAfterContentInit(){
  }



private update(): void {
  if (!this.router.navigated || !this.superclass) return;
      Promise.resolve().then(() => {
        this.previousUrl = this.router.url

        this.megaclass.toArray().forEach( (superclass) => {

          var superclass = superclass
          console.log( superclass.nativeElement.children[0].classList )
          console.log( superclass.nativeElement.children )

          if (this.previousUrl == superclass.nativeElement.getAttribute("routerLink")) {
            this.renderer.addClass(superclass.nativeElement.children[0], "box")
            console.log("add class")

          } else {
            this.renderer.removeClass(superclass.nativeElement.children[0], "box")
            console.log("remove class")
          }

        });
})
//update is done
}
ngOnDestroy(): void { this.subscription.unsubscribe(); }


//class is done
}

Uwaga :
W celu zaprogramowania należy dodać łącze do routera, ponieważ wymaga ono elementu potomnego. Jeśli chcesz to zmienić, musisz pozbyć się dzieci superclass.nativeElement.

grant mitchell soundbreakr1
źródło