Angular Routing

In questo articolo imparerai ad utilizzare Angular Routing per la navigazione tra le viste di un’applicazione Angular.

Hai mai sentito parlare di Single Page App? Una SPA permette di spostarsi tra le viste dell’applicazione senza necessità di ottenere una nuova pagina dal server. 

Allo stesso modo, Angular Routing serve per gestire la navigazione da una vista all’altra di un’applicazione Angular.

Come funziona Angular Routing?

Il router interpreta una URL del browser come un’istruzione per cambiare visualizzazione. Un componente Angular può essere quindi configurato come una pagina vera e propria dell’applicazione, pur conservando la struttura dell’applicazione a pagina singola: è la vista che cambia!.

 

Come utilizzare Angular Routing per la navigazione

In un post recente ho scritto come creare un’applicazione Angular utilizzando Angular CLI. Durante la creazione, ho suggerito di includere Angular Routing al progetto non appena questo è stato richiesto. Il modulo AppRoutingModule nel file app-routing.module.ts rappresenta il modulo di default per la configurazione dei percorsi: è qui, in particolare nella costante routes, che andrai a definire le viste (rotte) della tua applicazione, come vedrai tra poco.

Cartella file e codice di esempio
app-routing.module.ts
 

Aggiungere Angular Routing a un progetto Angular esistente

Per aggiungere Angular Routing a un progetto Angular esistente, devi installare la dipendenza @angular/router utilizzando npm:

npm install @angular/router

Crea il modulo AppRoutingModule (file app-routing.module.ts) e importalo in AppModule:

ng generate module app-routing --flat
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
...
import { AppRoutingModule } from './app-routing.module';

@NgModule({
  ...
  imports: [
    ...
    AppRoutingModule
  ]
})
export class AppModule { }

L’ultimo passo riguarda la direttiva router-outlet: il punto di ingresso per le viste. Aggiungi la direttiva al file app-component.html.

<router-outlet></router-outlet>

Nota sulla strategia pushState HTML5. Sebbene il router utilizzi lo stile per impostazione predefinita, è necessario configurare tale strategia. Aggiungi nella sezione <head> del file index.html il tag: 

<base href="/">

A questo punto, avrai aggiunto correttamente Angular Routing all’applicazione.

 

Utilizzare Angular Routing

Come avrai capito, Angular Routing permette di utilizzare componenti come fossero pagine dell’applicazione accessibili tramite URL. Infatti, ad ogni componente Angular è associato un template html per la sua rappresentazione.


Per ottenere questo risultato, devi creare un nuovo componente (vista) e configurare un percorso (route) associato alla vista.

Il primo percorso dovrebbe sempre essere il percorso vuoto (“”), che corrisponde alla rotta di default. Aggiungi successivamente tutti gli altri percorsi. I percorsi sono definiti all’interno della costante routes del modulo AppRoutingModule.

Se, ad esempio, vuoi definire la vista users che mostra la lista di tutti gli utenti registrati all’applicazione, aggiungi il percorso “users” come segue:

const routes: Routes = [
  {
    path: '',
    component: MainComponent
  },
  {
    path: 'users',
    component: UsersComponent
  }
}

Sarà responsabilità del componente UsersComponent implementare la visualizzazione della lista di tutti gli utenti. Per accedervi, basterà recarsi all’indirizzo /users.

 

Una volta definiti i percorsi, non resta che assegnare ai pulsanti il comportamento che permetta di spostarsi da una visualizzazione all’altra.

Per fare questo, puoi usare:

  • la direttiva routerLink
  • l’oggetto Router

Nel primo caso, aggiungi al template del componente (file .html) il pulsante, ad esempio:

<a routerLink="/users">Vedi gli utenti</a>

A differenza della direttiva routerLink che si applica direttamente al tag anchor HTML, l’oggetto Router viene utilizzato all’interno del file typescript del componente. In questo caso, dovrai implementare un metodo da chiamare utilizzando l’evento click del pulsante aggiunto nel template dello stesso componente: 

<button (click)="goToUsers()">Vedi gli utenti</button>
constructor(private readonly router: Router) { }

goToUsers() {
  this.router.navigate(['users']);
}
 

Percorsi annidati

Con Angular Router è possibile realizzare percorsi annidati, o nested routes. Questi tipi di percorsi sono chiamati percorsi “figli” o child routes

const routes: Routes = [
  {
    path: 'padre',
    component: ParentComponent,
    children: [
      {
        path: 'figlio',
        component: ChildComponent
      }
  }
}

In pratica, per realizzare un percorso annidato, devi aggiungere una (o più) vista nella pagina utilizzando la direttiva router-outlet, quindi nel template HTML del componente “padre”:

<p>Questo è il componente padre</p>
<router-outlet></router-outlet>
<p>Questo è il componente figlio</p>

Accedendo al percorso /padre ottieni il risultato:

Questo è il componente padre.

Accedendo al percorso /padre/figlio ottieni il risultato:

Questo è il componente padre.

Questo è il componente figlio.

 
const routes: Routes = [
  {
    path: '',
    component: WrapperComponent,
    children: [
      {
        path: 'users',
        component: UsersComponent
      },
      {
        path: 'users/:id',
        component: UserComponent
      },
      {
        path: ':id',
        component: PostComponent
      }
  }
}

Cosa hai appena visto?

Il percorso “users” non crea particolari preoccupazioni essendo simile alla definizione padre-figlio appena vista. Invece :id?

Angular Routing permette di definire dinamicamente i parametri della URL, assegnando a questi un valore associato ad una variabile. In questo caso, utilizza il data binding di Angular sul pulsante per accedere alla rotta:

<!-- /users/userId -->

<a routerLink="users/{{ userId }}">Vedi gli utenti</a>
<!-- oppure -->
<a [routerLink]="['users', userId]">Vedi gli utenti</a>

<!-- /postId -->

<a routerLink="{{ postId }}">Vedi il post {{ postId }}</a>
<!-- oppure -->
<a [routerLink]="[postId]">Vedi il post {{ postId }}</a>

oppure, con l’oggetto Router:

goToUser(id: string) {
  this.router.navigate(['users', id]);
}

In generale, è possibile realizzare percorsi complessi e richiamarli tramite array: [‘parte1’, variabile1, ‘parte2’, variabile2 …].

Ricorda, l’ordine è importante!. Nell’esempio, ad ogni percorso definito da un id (/1234, /pippo …) verrà utilizzato il componente PostComponent, ma se la variabile id assume il valore “users”, definito in ordine precedente nei percorsi, verrà utilizzato il componente UsersComponent.

 

Percorsi particolari

Esistono alcune rotte particolari alle quali è bene porre l’attenzione, come la pagina 404 e il redirect ad un percorso definito.

Pagina Not Found (404)

const routes: Routes = [
   { path: 'home', component: HomeComponent },
   { path: '**', component: PageNotFoundComponent }
];

Per ogni percorso non definito verrà utilizzato il componente PageNotFoundComponent.

Redirect

const routes: Routes = [
   { path: 'home', component: HomeComponent },
   { path: '',   redirectTo: '/home', pathMatch: 'full' },
   { path: '**', component: PageNotFoundComponent }
];

Il percorso di default “” rimanderà al componente HomeComponent.

 

Leggere i parametri dalla URL: query e path params

Hai appena visto come utilizzare Angular Routing per la navigazione, definendo un percorso e richiamandolo tramite un pulsante. Avrai notato come un percorso può essere più o meno articolato e che questo corrisponde sempre ad un componente.

Ma come faccio a leggere la URL del percorso raggiunto?

È possibile accedere alla URL e a tutti i parametri attraverso l’oggetto ActivatedRoute della libreria. 

Nell’esempio visto poco fa, quando si è parlato di percorsi annidati, ho aggiunto il percorso “:id” associato al componente PostComponentCome leggo il parametro id dalla URL?

constructor(
    private readonly route: ActivatedRoute
) { 
    this.route.params
        .subscribe(p => {
            // p.id ...
    }
}

Utilizzando l’attributo params di ActivatedRoute è possibile accedere al parametro id, e a tutti gli altri se presenti, contenuto nella URL. È possibile recuperare allo stesso modo i parametri query (?nome=pippo&…) presenti tramite l’attributo queryParams oltre ad altre informazioni riguardanti il router. 

constructor(
    private readonly route: ActivatedRoute
) { 
    this.route.queryParams
        .subscribe(qp => {
            // qp.category ...
    }
}

<a [routerLink]="[postId]" [queryParams]="{ category: 'blog'}">Vedi il post {{ postId }}</a>
this.router.navigate([postId], { queryParams: { category: 'blog' } });
 

E adesso?

Hai appena visto un modo per utilizzare Angular Routing per la navigazioneEsistono altre funzionalità riguardanti Angular Routing, come il caricamento dei componenti lazy loading, l’utilizzo di resolvers, piuttosto che l’utilizzo di guards.

Se vuoi sapere di più su Angular, Angular Routing e altro, guarda l’esempio completo che ho scritto per te!. 

Link di riferimento:

Recommended Posts

No comment yet, add your voice below!


Add a Comment

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *