En Angular, ¿cómo se determina la ruta activa?

312

NOTA: Aquí hay muchas respuestas diferentes, y la mayoría han sido válidas en un momento u otro. El hecho es que lo que funciona ha cambiado varias veces a medida que el equipo de Angular ha cambiado su enrutador. La versión Router 3.0 que eventualmente será el enrutador en Angular rompe muchas de estas soluciones, pero ofrece una solución muy simple propia. A partir de RC.3, la solución preferida es usar [routerLinkActive]como se muestra en esta respuesta .

En una aplicación angular (actual en la versión 2.0.0-beta.0 mientras escribo esto), ¿cómo determina cuál es la ruta actualmente activa?

Estoy trabajando en una aplicación que usa Bootstrap 4 y necesito una forma de marcar los enlaces / botones de navegación como activos cuando su componente asociado se muestra en una <router-output>etiqueta.

Me doy cuenta de que podría mantener el estado yo mismo cuando se hace clic en uno de los botones, pero eso no cubriría el caso de tener múltiples rutas en la misma ruta (por ejemplo, un menú de navegación principal y un menú local en el componente principal). )

Cualquier sugerencia o enlaces serán apreciados. Gracias.

Michael Oryl
fuente

Respuestas:

356

Con el nuevo enrutador angular , puede agregar un [routerLinkActive]="['your-class-name']"atributo a todos sus enlaces:

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

O el formato simplificado sin matriz si solo se necesita una clase:

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

O un formato aún más simple si solo se necesita una clase:

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

Consulte la directiva mal documentadarouterLinkActive para obtener más información. (Principalmente lo descubrí a través de prueba y error).

ACTUALIZACIÓN: routerLinkActiveAhora se puede encontrar una mejor documentación para la directiva aquí . (Gracias a @Victor Hugo Arango A. en los comentarios a continuación).

jessepinho
fuente
44
¿Hay alguna forma de que se active cuando los hijos de la ruta están activos? El código tiene @inputopciones for, pero exact: falseactiva la clase siempre que los hermanos de la ruta actual también estén activos.
Matej
1
@ GabrieleB-David No lo he probado, pero supongo que router.navigate()funcionaría bien. routerLinkActivees simplemente un indicador de si este enlace representa la ruta activa.
jessepinho
77
En el ejemplo dado, [routerLinkActive] se agrega a la etiqueta <a />, sin embargo, también se puede colocar en otros elementos si la clase se requiere en otro lugar. <ul> <li [routerLinkActive] = "['active']"> <a [routerLinkfont>="[myRoute.Routefont>">
Oblivion2000
2
@jessepinho - Probé - [routerLinkActive] = "'active'" solo funcionará si también tienes [routerLink] en la etiqueta a. Si tenía (click) = "navitageTo ('/ route')" en lugar de [routerLink], y en esa función, llamó this.router.navigate (route), el nuevo componente se cargará pero su clase CSS activa ganó ' t ser aplicado. Estoy tratando de hacer algo más en esa función además de this.router.navigate (..).
Mickael Caruso
2
El ejemplo en la documentación oficial podría ayudarlo: angular.io/docs/ts/latest/api/router/index/…
Victor Hugo Arango A.
69

He respondido esto en otra pregunta, pero creo que también podría ser relevante para esta. Aquí hay un enlace a la respuesta original: Angular 2: ¿Cómo determinar la ruta activa con parámetros?

He estado tratando de configurar la clase activa sin tener que saber exactamente cuál es la ubicación actual (usando el nombre de la ruta) . La mejor solución a la que he llegado hasta ahora es usar la función isRouteActive disponible en la Routerclase.

router.isRouteActive(instruction): Booleantoma un parámetro que es un Instructionobjeto de ruta y devuelve trueo falsesi esa instrucción es verdadera o no para la ruta actual. Puede generar una ruta Instructionmediante el uso de Router' generate (linkParams: Array) . LinkParams sigue exactamente el mismo formato que un valor pasado a una directiva routerLink (por ejemplo router.isRouteActive(router.generate(['/User', { user: user.id }]))).

Así es como podría verse el RouteConfig (lo modifiqué un poco para mostrar el uso de los parámetros) :

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

Y la Vista se vería así:

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

Esta ha sido mi solución preferida para el problema hasta ahora, también puede ser útil para usted.

Alex Santos
fuente
1
Creo que esta solución es mejor que la aceptada, ya que utiliza API angulares en lugar de expresiones regulares que coinciden con la ruta. Sin embargo, todavía es un poco feo, sería bueno poder hacerlo router.isRouteActive('Home').
Philip
2
Me enfrenté a algunos problemas al intentar implementar la solución, por lo que tal vez para algunos pueda ser útil: stackoverflow.com/questions/35882998/…
Nikita Vlasenko
55
no debe olvidar poner Routeren constructor de clase
Nikita Vlasenko
2
En la última versión de Angular 2 que utilicé en namelugar del asobjeto de configuración del enrutador.
ComFreek
99
Esto se puede usar en rc1 en su lugar:router.urlTree.contains(router.createUrlTree(['Home']))
František Žiačik
35

Resolví un problema que encontré en este enlace y descubrí que hay una solución simple para su pregunta. En su router-link-activelugar, podría usar en sus estilos.

@Component({
   styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
Quy Tang
fuente
2
Creo que esta debería ser la respuesta aceptada. El enrutador de Angular2 agregará esto automáticamente por usted.
Gabu
2
desafortunadamente, esa clase agrega en <a>, no en <li>
laifjei
desafortunadamente no funciona realmente bien. Tengo un menú generado dinámicamente y la router-link-activeclase no se agrega al activo ao li. pero hay un lugar donde estoy usando bootstrap nav-tabsy funciona allí.
Shri
33

Pequeña mejora a la respuesta de @ alex-correia-santos basada en 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));
  }
} 

Y úsalo así:

<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
fuente
y un estilo en el componente styles : [.active {background-color: aliceblue; } ]. +1 funciona
Pratik Kelwalkar
Gran solución, con esto puede hacer que el enrutador sea privado.
Kelvin Dealca
¡Esta es una solución mucho mejor y es especialmente útil para un novato que olvida pequeñas cosas como crear el constructor y pasar el enrutador! Te mereces totalmente el cheque.
Metodista
30

Puede verificar la ruta actual inyectando el Locationobjeto en su controlador y verificando path()así:

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

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

Tendrás que asegurarte de importarlo primero:

import {Location} from "angular2/router";

Luego puede usar una expresión regular para hacer coincidir la ruta que se devuelve para ver qué ruta está activa. Tenga en cuenta que la Locationclase devuelve una ruta normalizada independientemente de cuál LocationStrategyesté usando. Por lo tanto, incluso si está utilizando las HashLocationStragegyrutas devueltas seguirán siendo de la forma /foo/bar no #/foo/bar

Jason Teplitz
fuente
17

¿Cómo se determina cuál es la ruta actualmente activa?

ACTUALIZACIÓN: actualizado según 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
}

ver más...

Ankit Singh
fuente
14

Para marcar rutas activas routerLinkActivese puede utilizar

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

Esto también funciona en otros elementos como

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

Si las coincidencias parciales también deben marcarse, use

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

Hasta donde sé, exact: falseserá el valor predeterminado en RC.4

Günter Zöchbauer
fuente
11

En este momento estoy usando rc.4 con bootstrap 4 y este funciona perfecto para mí:

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

Esto funcionará para url: / home

Artem Zinoviev
fuente
¿Cuál es el propósito de la opción exacta? ¿Eso hace que no coincida con subrutas como /home/whatever?
Michael Oryl
Sí, es exactdecir, esa ruta tendrá el mismo nombre. Y esto es necesario si planea usarlo con herramientas como Twitter Bootstrap. Ya maneja el estado del enlace activo y sin exactopción no funcionará. (no estoy seguro de cómo funciona en el núcleo, lo probé y funciona para mí)
Artem Zinoviev
7

A continuación se muestra el método que utiliza RouteData para diseñar elementos de la barra de menú según la ruta actual:

RouteConfig incluye datos con pestaña (ruta actual):

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

Una pieza de diseño:

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

Clase:

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

Solo pensé que agregaría un ejemplo que no usa ningún mecanografiado:

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

La routerLinkActivevariable está vinculada a una variable de plantilla y luego se reutiliza según sea necesario. Desafortunadamente, la única advertencia es que no puede tener todo esto en el <section>elemento, ya #homeque debe resolverse antes de que se ejecute el analizador <section>.

Zze
fuente
Solución perfecta para aplicar condiciones en rutas activas. Donde @ angular / router o no funcionó.
Rohit Parte
Wow, esto es muy útil. ¡Gracias!
Yulian
6

Routeren Angular 2 RC ya no define isRouteActivey generatemétodos.

urlTree - Devuelve el árbol de URL actual.

createUrlTree(commands: any[], segment?: RouteSegment) - Aplica una matriz de comandos al árbol de URL actual y crea un nuevo árbol de URL.

Intenta seguir

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

aviso, routeSegment : RouteSegmentdebe inyectarse en el constructor del componente.

tchelidze
fuente
6

Aquí hay un ejemplo completo para agregar un estilo de ruta activo en la versión angular 2.0.0-rc.1que tiene en cuenta las rutas raíz nulas (por ejemplo path: '/')

app.component.ts -> Rutas

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

Solución para 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
fuente
5

A partir de Angular 8, esto funciona:

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

{ exact: true } asegura que coincida con la url.

codejockie
fuente
5

en 2020 si desea establecer la clase activa en un elemento que no tiene [routerLink], puede hacer simplemente:

<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
fuente
Gracias Igor Esta es la mejor solución.
Dmitry Grinko
Gracias por sus comentarios :)
Kurkov Igor
4

Otra solución alternativa. Mucho más fácil en Angular Router V3 Alpha. inyectando el enrutador

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

export class AppComponent{

    constructor(private router : Router){}

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

uso

<div *ngIf="routeIsActive('/')"> My content </div>
shakee93
fuente
Tan pronto como lo importo, aparece la propiedad No se puede leer 'isSkipSelf' de error nulo. ¿algunas ideas?
atsituab
4

En Angular2 RC2 puedes usar esta implementación simple

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

esto agregará clase activeal elemento con url coincidente, lea más sobre esto aquí

Khaled Al-Ansari
fuente
4

A continuación se encuentran las respuestas a esta pregunta para todas las versiones de Angular 2 RC lanzadas hasta la fecha:

RC4 y RC3 :

Para aplicar la clase al enlace o al antecesor del enlace:

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

/ home debería ser la URL y no el nombre de la ruta, ya que la propiedad de nombre ya no existe en el objeto de ruta a partir del enrutador v3.

Más información sobre la directiva routerLinkActive en este enlace .

Para aplicar la clase a cualquier div en función de la ruta actual:

  • Inyecte el enrutador en el constructor del componente.
  • Usuario router.url para comparación.

p.ej

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

RC2 y RC1 :

Use la combinación de router.isRouteActive y class. *. por ejemplo, para aplicar la clase activa basada en la ruta local.

El nombre y la URL se pueden pasar al router.generate.

 <li [class.active]="router.isRouteActive(router.generate(['Home']))">
    <a [routerLink]="['Home']" >Home</a>
</li>
Inderdeep Singh
fuente
4

El uso routerLinkActivees bueno en casos simples, cuando hay un enlace y desea aplicar algunas clases. Pero en casos más complejos donde es posible que no tenga un routerLink o donde necesite algo más, puede crear y usar una tubería :

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

luego:

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

y no olvides incluir la tubería en las dependencias de las tuberías;)

pleerock
fuente
Buena idea, pero en angular2.0.0rc3 cambio this.router.isRouteActive ... a this._location.path () y agrego esto: import {Location} desde '@ angular / common';
Kamil Kiełczewski
2
Parece que falta algo del código. ¿Dónde se containsTreedefine?
Øystein Amundsen
4

Para la versión angular 4+, no necesita usar ninguna solución compleja. Simplemente puedes usar [routerLinkActive]="'is-active'".

Para un ejemplo con el enlace de navegación 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
fuente
3

Una instancia de la clase Router es en realidad un Observable y devuelve la ruta actual cada vez que cambia. Así es como lo hago:

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

Y luego en mi HTML:

<a [routerLink]="['Contact']" class="item" [class.active]="isCurrentRoute('contact')">Contact</a>
Anees Dhansey
fuente
1
.subscribe no está disponible en la instancia del enrutador.
Shivang Gupta
3

Como se menciona en uno de los comentarios de la respuesta aceptada, la routerLinkActivedirectiva también se puede aplicar a un contenedor de la <a>etiqueta real .

Entonces, por ejemplo, con las pestañas Bootstrap de Twitter, donde la clase activa debe aplicarse a la <li>etiqueta que contiene el enlace:

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

Con buena pinta ! Supongo que la directiva inspecciona el contenido de la etiqueta y busca una <a>etiqueta con la routerLinkdirectiva.

Pierre Henry
fuente
2

La solución simple para los usuarios de angular 5 es simplemente agregar routerLinkActiveal elemento de la lista.

Una routerLinkActivedirectiva está asociada con una ruta a través de una routerLinkdirectiva.

Toma como entrada una matriz de clases que agregará al elemento al que está adjunto si su ruta está actualmente activa, de esta manera:

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

Lo anterior agregará una clase de activo a la etiqueta de ancla si actualmente estamos viendo la ruta de inicio.

Manifestación

Prasanth Jaya
fuente
2

Y en la última versión de angular, simplemente puede verificar router.isActive(routeNameAsString). Por ejemplo, vea el siguiente ejemplo:

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

Y asegúrese de no olvidarse de inyectar enrutador en su componente.

ConductedClever
fuente
1

Estaba buscando una manera de usar un navegador de estilo Bootstrap de Twitter con Angular2, pero tuve problemas para activeaplicar la clase al elemento padre del enlace seleccionado. ¡Descubrí que la solución de @ alex-correia-santos funciona perfectamente!

El componente que contiene sus pestañas tiene que importar el enrutador y definirlo en su constructor antes de que pueda realizar las llamadas necesarias.

Aquí hay una versión simplificada de mi implementación ...

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

supongamos que desea agregar CSS a mi estado / pestaña activa. Use routerLinkActive para activar su enlace de enrutamiento.

nota: 'activo' es mi nombre de clase aquí

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

Estoy usando un enrutador angular ^3.4.7y todavía tengo problemas con la routerLinkActivedirectiva.

No funciona si tiene varios enlaces con la misma URL, además no parece actualizarse todo el tiempo.

Inspirado por la respuesta de @tomaszbak, creé un pequeño componente para hacer el trabajo

RPDeshaies
fuente
0

La plantilla html pura será como

 <a [routerLink]="['/home']" routerLinkActive="active">Home</a>
 <a [routerLink]="['/about']" routerLinkActive="active">About us</a>
 <a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>
Bellash
fuente
0

comience importando RouterLinkActive en sus archivos .ts

importar {RouterLinkActive} desde '@ angular / router';

Ahora use RouterLinkActive en su HTML

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

proporcione algunos css a la clase "class_Name", ya que cuando este enlace esté activo / haga clic, encontrará esta clase en el intervalo durante la inspección.

T. Shashwat
fuente
0

Una forma programática sería hacerlo en el componente mismo. Tuve problemas durante tres semanas en este tema, pero me di por vencido en documentos angulares y leí el código real que hizo que routerlinkactive funcionara y eso es sobre los mejores documentos que puedo encontrar.

    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
}

Nota :
Para la forma programática, asegúrese de agregar el enrutador-enlace y toma un elemento hijo. Si desea cambiar eso, debe deshacerse de los niños superclass.nativeElement.

Grant Mitchell Soundbreakr1
fuente