Cómo manejar el router de Angular

Última actualización:

Cómo crear rutas en Angular. Sistema de routing

Si ya sabes cómo se crean los Componentes en Angular lo siguiente que puedes hacer es asignarlos a ciertas rutas para que el usuario pueda navegar por la web.

Por ejemplo, imagina que quieres crear la página /users. Pues lo primero que tienes que hacer es crear el componente UsersComponent (o como quieras llamarlo)

Por ejemplo:

// app/users/users.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})

export class UsersComponent  {

  constructor() { }

}

Para asignar este componente a una ruta necesitamos hacer uso del routing de Angular, necesitamos el archivo con las rutas.

Creamos un archivo al mismo nivel que el app.module.ts y lo llamamos app.routing.ts.

Una vez creado importamos las rutas de Angular:

import { RouterModule, Routes } from '@angular/router';

Ahora, creamos una variable que guardará la lista de todas las rutas de la web:

const appRoutes = [
  { path: '', component: UsersComponent,  pathMatch: 'full'}
];
  • path: La ruta a que queremos configurar
  • component: Componente asociado a esa ruta. Para que funcione tienes que importar el componente en la parte de arriba, por ejemplo:

    import { UsersComponent } from './users/users.component';
    
  • pathMatch: Esto es opcional, significa que toda la ruta URL tiene que coincidir (no solo cierta parte).

El fichero completo, quedaría de la siguiente manera:

// app.routing.ts
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { UsersComponent } from './users/users.component';

const appRoutes = [
  { path: 'users', component: UsersComponent,  pathMatch: 'full'},
];
export const routing = RouterModule.forRoot(appRoutes);

Solo con esa ruta. Ahora, tenemos que importar las rutas en el archivo app.module.ts, para ello importamos la ruta y lo añadimos, esta vez en la parte de imports:

import { routing } from './app.routing';

...

  imports: [
    BrowserModule,
    routing
  ],

Si tienes la web ejecutándose con ng serve (para el comando y vuelve a arrancarlo para que pille la nueva ruta) y abres la url localhost:4200/users verás que se renderiza el contenido del HTML del componente de Users.

Creando rutas con partes dinámicas

Ahora, imaginemos que queremos crear una página para mostrar en detalle items de una lista. Por ejemplo queremos tener /item/1, /item/2, /item/3, etc. En lugar de crear cada una de esas rutas, puedes configurar que cierta parte de la ruta sea dinámica, es decir, que Angular genere todas las rutas por tí. Para ello tienes que poner dentro del path, a continuación de la barra /, dos puntos y nombre que quieras para esa variable:

const appRoutes = [
 { path: 'items', component: ItemListComponent,  pathMatch: 'full'},
 { path: 'item/:id', component: ItemDetailComponent }
];

Siempre y cuando hayas creado dos nuevos componentes, ItemListComponent y ItemDetailComponent (o como quieras llamarlos).

Con esto se crean todas las rutas posibles que empiecen por /item. El nombre id sive para guardar en esa variable la ruta específica en la que estamos, es decir, luego dentro del componente ItemDetailComponent puedes recoger ese valor para saber en qué ruta estás. Para ello dentro del constructor:

// item-detail.component.ts

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

...

constructor(private route: ActivatedRoute) {
  console.log(route.snapshot.params['id'];)
}

Recuerda importar ActivatedRoute e inyectarlo dentro del constructor con el nombre que quieras.

Se imprimirá por consola el valor que aparece en la ruta, es decir, si navegamos a la ruta /item/2, se imprimirá 2 y si navegamos a /item/foo se imprimirá foo.

¿Qué es el Router outlet de Angular?

Si pruebas las páginas con estos cambios te darás cuenta de que todavía no se muestran las nuevas rutas, esto pasa el primer componente que se carga siempre es app.component.html y como ese archivo ya tiene un HTML es el que se pintará.

IMPORTANTE: Por el momento (luego se puede cambiar) todas las rutas son hijas de app.component.

Dentro del app.component.html tenemos que incluir una etiqueta especial de Angular:

<!-- app.component.html -->

<router-outlet></router-outlet>

router-outlet es una etiqueta especial en Angular que sirve para mostrar los componentes hijos de un componente. Por defecto todos los componentes son hijos del componente AppComponent, por lo que si incluímos esta etiqueta dentro de la vista de AppComponent, se renderizará cada uno de los componentes del routing dependiendo de la página en la que nos encontremos.

Se imprimirá por consola el valor que aparece en la ruta, es decir, si navegamos a la ruta /items, se sustituirá la etiqieta router-outlet por el componente que esté asignado en ela archivo de rutas para ese componente.

Con esto por ejemplo puedes hacer que el componente app-component.html tenga el navbar para que así se pinte en todas las rutas (siempre que exista el conponente de navbar y lo hayas importado en el app.module.ts):

<!-- navbar.component.html -->

<app-navbar></app-navbar>
<router-outlet></router-outlet>

Componentes hijos

Veamos ahora como crear rutas hijas. Esto es muy útil por lo que hemos hablado antes, puedes definir una ruta que tenga una o varias rutas hijas, así consigues que el HTML que pongas en el componente padre se rendericé también en cada una de las rutas hijas. Veamos un eejemplo:

// app.routing.ts

const appRoutes = [
  {
    path: 'admin', component: AdminComponent,
    children: [
      { path: '', component: AdminMainComponent, },
      { path: 'settings', component: SettingsComponent }          
    ]
  }
];

En este ejemplo, la página de admin tiene dos componentes hijos. Para ello se crea la propiedad children dentro del objeto con la ruta que será un array de rutas.

En la ruta /admin/ se cargará el componente MainComponent y en la ruta /admin/settings, el componente SettingsComponent

Los componentes hijos se dibujarán en el router outlet que coloquemos en el padre, es decir para que se renderizen estos componentes, tenemos que poner en la vista del AdminComponent un router-outlet. T

odo lo que incluyamos en la vista del AdminComponent se visualizará también en las dos páginas hijas.

Ya no podemos usar el atributo href, de no ser que queramos navegar a una página fuera de la web.

Para poner un link ahora tenemos que usar esta etiqueta especial de Angular:

  <a routerLink="/list" routerLinkActive="active">Link</a>

De esta manera, por ejemplo, navegaremos a la url /list, y si la tenemos configurada en el app.routing.ts se cargará su vista dentro del router-outlet del componente padre de esa ruta.