Rutas en Angular: mostrar la ruta activa

  • Por
Cómo mostrar la ruta activa en el navegador de una aplicación Angular, aquella que se está mostrando en este momento.

Después de incursionar en el sistema de routing de Angular, en un artículo que contuvo mucha información, vamos a realizar un paso bastante más simple, pero esencial para la usabilidad de las aplicaciones. Se trata de marcar la ruta activa en el navegador.

Por supuesto, la aplicación de estilos es una responsabilidad del CSS, por lo que tendremos una clase "activo" o con algún nombre similar, que usaremos para aplicar el estilo. Sin embargo esa clase se debe aplicar dinámicamente al elemento que toque en cada momento y eso es lo que tenemos que hacer con Angular.

Afortunadamente, esta parte es bastante sencilla, gracias a una directiva que permite aplicar una clase CSS cuando el navegador está mostrando una ruta determinada.

Directiva routerLinkActive

La directiva de Angular routerLinkActive es la que nos permite aplicar una clase dinámicamente, dependiendo de si un enlace determinado tiene su ruta activa. La forma de trabajar en principio es bien sencilla, como veremos a continuación.

Como cualquier cosa en Angular, comenzamos importando en el TypeScript del componente la directiva que pretendemos usar.

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

En el siguiente código tenemos una primera aproximación, aplicando la directiva routerLinkActive al navegador, en nuestro template. Aunque todavía no es exactamente la más completa, enseguida veremos por qué.

<nav>
  <a routerLink="/" routerLinkActive="activo">Home</a> | 
  <a routerLink="/contacto" routerLinkActive="activo">Contacto</a> | 
  <a routerLink="/quienessomos" routerLinkActive="activo">Quienes somos</a> 
</nav>

Como puedes comprobar en el código anterior, se ha aplicado una clase llamada "activo", por lo que tendrás que crear esta clase en el CSS del componente, claro está. Si no, no habrá ningún CSS que aplicar.

Un detalle interesante con respecto a Angular es que hemos colocado un string literal como valor a la directiva. Por eso la directiva no se aplica con los corchetes, porque lo que hay entre comillas como valor no es una variable o una expresión que se tenga que evaluar, sino simplemente una cadena literal: "activo".

Nota: Observa que hemos creado una ruta adicional, con respecto al ejercicio tal como lo dejamos en el artículo anterior. Esto te obligará a practicar un poco, creando la ruta en el array de Routes y luego el componente correspondiente. Esto te lo dejamos para ti.

Aplicación de routerLinkActive sobre el contenedor

Hay veces que el CSS no lo quieres aplicar al propio enlace, sino a su contenedor. Esto no es un problema para routerLinkActive, que también funciona si tienes que aplicar esa clase dinámicamente al padre donde está el enlace de navegación.

Por ejemplo imagina que tienes una lista y que el estilo del elemento activo debe colocarse en el elemento LI. No habría problema para conseguir ese detalle, de la siguiente manera.

Nuestro template podría entonces tener esta forma:

<nav>
  <ul>
    <li routerLinkActive="activo">
      <a routerLink="/">Home</a>
    </li>
    <li routerLinkActive="activo">
      <a routerLink="/contacto">Contacto</a>
    </li>
    <li routerLinkActive="activo">
      <a routerLink="/quienessomos">Quienes somos</a>
    </li>
  </ul>
</nav>

Y aunque este no es un Manual de CSS, podríamos aplicar unos estilos como estos:

.activo {
  background-color: #ccc;  
}
.activo a {
  color: green;
}
ul {
  list-style: none;
}
li {
  display: inline-block;
  margin-right: 20px;
  background-color: #eee;
  padding: 15px;
}

Aplicar estilo sólo a la ruta exacta

Si ejecutas tu aplicación, tal como la hemos dejado, podrás apreciar que tenemos un pequeño problema. El enlace de "home" aparece siempre como activo. Es decir, navegamos a las otras secciones del sitio, que se marcan correctamente como activo, pero el enlace de "home" siempre permanece como activo también.

No es un error, está funcionando tal como se espera. Por defecto, routerLinkActive marca como activo a un enlace del navegador que contenga la ruta, no que sea exactamente esa ruta.

Me explico. En rutas como http://localhost:4200/quienessomos la ruta exacta es "/quienessomos", pero la ruta raíz "/" está contenida en "/quienessomos". Por tanto ocurre que al visitar "/quienessomos" se marcan como activos dos enlaces, el raíz y el "quienessomos".

Esto podría no ser un problema en algunos casos, pero si no te gusta se puede solucionar perfectamente. Para ello tenemos que conocer un configurador llamado "routerLinkActiveOptions".

Nota: Como enseguida verás en el código, routerLinkActiveOptions podría parecer una nueva directiva, pero realmente no lo es. Forma parte de la directiva routerLinkActive y sirve para configurar el comportamiento de ésta. Como no es una directiva, sino que forma parte de la directiva que ya venimos usando, no hace falta que hagamos el import de routerLinkActiveOptions.

Esta configuración de la directiva nos aporta la posibilidad de configurar, mediante un objeto, algunas opciones para marcar el enlace activo. La que necesitamos usar se llama "exact". Aplicada a nuestro template, nos quedaría más o menos como esto:

<nav>
  <ul>
    <li routerLinkActive="activo" [routerLinkActiveOptions]="{exact: true}">
      <a routerLink="/">Home</a>
    </li>
    <li routerLinkActive="activo">
      <a routerLink="/contacto">Contacto</a>
    </li>
    <li routerLinkActive="activo">
      <a routerLink="/quienessomos">Quienes somos</a>
    </li>
  </ul>
</nav>

Fíjate en los siguientes puntos:

  • Ahora sí necesitamos poner usar la notación de corchetes en routerLinkActiveOptions, porque lo que estamos pasando no es una cadena, sino algo de Javascript que se tiene que evaluar. En este caso le pasamos un objeto.
  • En el objeto, colocamos "exact" con el valor true, lo que indica que este enlace sólo se marcará como activo si la ruta exacta es "/".

Ahora, si ejecutas tu ejemplo podrás observar que está tal como hubiéramos deseado, marcando sólo como activa la ruta que se necesita en cada caso.

Conclusión

Ya tenemos las herramientas necesarias para hacer un bonito navegador, usando rutas internas de la aplicación. Nuestro sistema de routing en Angular está cada vez más configurado y gracias a este conocimiento podremos hacer aplicaciones con un aspecto más profesional.