Maîtriser Angular : Développement d'Applications Web Modernes et Robustes
Maîtriser Angular : Développement d'Applications Web Modernes et Robustes

Routage et Navigation : Gérer les Vues de l'Application

Introduction : L'Art de la Navigation dans les Applications Monopages

Dans le monde du développement web moderne, les utilisateurs s'attendent à des applications rapides, fluides et réactives. Les applications web traditionnelles, qui rechargent une page complète à chaque clic sur un lien, offrent une expérience qui peut sembler lente et saccadée. C'est là que les Single Page Applications (SPAs), comme celles développées avec Angular, entrent en jeu.

Une SPA charge une seule fois l'intégralité du code HTML, CSS et JavaScript, puis met à jour dynamiquement le contenu de la page sans nécessiter de rechargements complets. Mais comment une SPA gère-t-elle la navigation entre différentes "vues" ou "pages" sans ces rechargements ? La réponse réside dans le système de routage.

Le Router Angular est le composant clé qui permet à votre application de simuler la navigation entre plusieurs pages en modifiant l'URL du navigateur, tout en affichant les composants Angular appropriés sans recharger l'intégralité de la page. C'est le cerveau qui orchestre le passage d'une vue à l'autre, offrant une expérience utilisateur fluide et intuitive.

Dans cette leçon, nous allons explorer en détail comment configurer et utiliser le Router Angular pour gérer efficacement les vues de votre application :

  • Comprendre les principes fondamentaux du routage.
  • Mettre en place le module de routage.
  • Définir les routes et associer des composants.
  • Afficher les vues routées à l'aide de <router-outlet>.
  • Naviguer de manière déclarative avec routerLink et de manière programmatique avec le service Router.
  • Gérer les paramètres passés via l'URL.
  • Aperçu des concepts avancés comme le chargement paresseux et les gardiens de route.

Préparez-vous à donner à vos applications Angular la capacité de naviguer avec élégance !


I. Comprendre le Routage dans Angular

Qu'est-ce que le Routage ?

Le routage, dans le contexte d'une application web, est le processus par lequel l'application mappe une URL spécifique à un composant (ou une vue) particulier et l'affiche à l'utilisateur.

  • Applications traditionnelles : Chaque URL correspond à un fichier HTML distinct sur le serveur. Naviguer vers une nouvelle URL entraîne un rechargement complet de la page depuis le serveur.
  • Applications monopages (SPAs) : Le routage est géré côté client (par le navigateur et le framework JavaScript). Lorsque l'URL change, le Router Angular intercepte ce changement, détermine quel composant doit être affiché, et le charge dynamiquement dans une zone dédiée de la page, sans rechargement complet.

Avantages du routage côté client :

  • Rapidité : Pas de rechargement de page, ce qui rend l'application plus rapide et plus réactive.
  • Fluidité : Transition douce entre les vues, améliorant l'expérience utilisateur.
  • État de l'application : Permet de maintenir l'état de l'application (par exemple, les données dans un formulaire) lors des changements de vue.
  • Partage : Les URL peuvent toujours être partagées, mises en signet et utilisées pour naviguer directement vers un état spécifique de l'application.

Le Router Angular : Le Cœur de la Navigation

Le Router Angular est un module puissant fourni par le framework qui facilite la gestion de la navigation au sein de votre SPA. Il est basé sur le module @angular/router.

Ses principales fonctionnalités incluent :

  • Définition de routes : Vous permet d'associer des chemins d'URL à des composants Angular spécifiques.
  • Navigation : Offre des mécanismes pour naviguer entre les vues, que ce soit via des liens dans le template ou de manière programmatique depuis le code TypeScript.
  • Gestion des paramètres : Permet de passer des données (identifiants, filtres, etc.) d'une vue à l'autre via l'URL.
  • Gardiens de route (Guards) : Fournit des "gardes" pour contrôler l'accès aux routes (par exemple, vérifier l'authentification ou l'autorisation avant d'afficher une vue).
  • Stratégies de chargement : Prend en charge le chargement paresseux (lazy loading) des modules, ce qui améliore considérablement les performances des grandes applications en ne chargeant le code que lorsque c'il est nécessaire.

II. Configuration et Définition des Routes de Base

Pour commencer à utiliser le routage dans votre application Angular, vous devez configurer le module de routage et définir les routes.

1. Initialisation du Module de Routage

Lorsque vous créez une nouvelle application Angular avec ng new votre-app --routing, Angular génère automatiquement un fichier app-routing.module.ts pour vous. Si vous l'ajoutez plus tard, vous pouvez utiliser ng generate module app-routing --flat --module=app.

Ce module gère la configuration des routes de votre application.

// src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

// Importez les composants que vous souhaitez lier à des routes
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ContactComponent } from './contact/contact.component';
import { NotFoundComponent } from './not-found/not-found.component'; // Pour la gestion 404

// Définition des routes de l'application
const routes: Routes = [
  // Route par défaut : redirige l'URL vide vers le composant HomeComponent
  { path: '', component: HomeComponent },
  // Route pour la page "À Propos"
  { path: 'about', component: AboutComponent },
  // Route pour la page "Contact"
  { path: 'contact', component: ContactComponent },
  // Route générique (wildcard) : redirige toutes les autres URL vers NotFoundComponent
  // IMPORTANT : Cette route doit être la DERNIÈRE dans votre tableau
  { path: '**', component: NotFoundComponent }
];

@NgModule({
  // configure le module de routage principal avec les routes définies
  imports: [RouterModule.forRoot(routes)],
  // rend le RouterModule disponible pour les autres modules de l'application
  exports: [RouterModule]
})
export class AppRoutingModule { }

Explication du code :

  • import { RouterModule, Routes } from '@angular/router';: Importe les modules nécessaires du package @angular/router.
  • const routes: Routes = [...]: C'est ici que vous définissez vos routes. Routes est une interface d'Angular qui représente un tableau de définitions de routes.
  • { path: '', component: HomeComponent }: Définit une route.
    • path: Le segment d'URL (chemin) qui active cette route. Ici, '' représente la racine de l'application (par exemple, http://localhost:4200/).
    • component: Le composant Angular qui sera affiché lorsque cette route est activée.
  • { path: '**', component: NotFoundComponent }: C'est une route générique (wildcard). Le ** signifie "n'importe quel chemin non défini précédemment". Il est crucial de la placer en dernier dans votre tableau de Routes, car le routeur parcourt les routes de haut en bas et s'arrête à la première correspondance. Elle est souvent utilisée pour afficher une page 404 "Page Non Trouvée".

Le RouterModule.forRoot(routes) est utilisé dans le module racine de l'application (AppModule) pour enregistrer les routes principales. Il configure également le service de routage, y compris l'écoute des changements d'URL. Pour les modules de fonctionnalités (abordé plus tard avec le lazy loading), vous utiliseriez RouterModule.forChild(routes).

2. L'Emplacement du Contenu Routé : <router-outlet>

Le Router Angular a besoin d'un endroit pour afficher les composants qui correspondent à la route active. C'est le rôle du composant <router-outlet>.

Vous placez généralement <router-outlet> dans le template du composant racine de votre application, app.component.html, ou dans un autre composant de mise en page où vous souhaitez que le contenu routé s'affiche.

<!-- src/app/app.component.html -->
<header>
  <h1>Mon Application Angular</h1>
  <nav>
    <ul>
      <!-- Liens de navigation définis plus bas -->
      <li><a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">Accueil</a></li>
      <li><a routerLink="/about" routerLinkActive="active">À Propos</a></li>
      <li><a routerLink="/contact" routerLinkActive="active">Contact</a></li>
    </ul>
  </nav>
</header>

<main class="content">
  <!-- C'est ici que les composants routés seront chargés -->
  <router-outlet></router-outlet>
</main>

<footer>
  <p>&copy; 2023 Mon Application Angular</p>
</footer>

Explication :

  • Le <router-outlet> agit comme un placeholder. Lorsque l'URL correspond à une route, Angular prend le composant associé à cette route et l'injecte à l'intérieur du <router-outlet>.
  • Lorsque l'URL change et correspond à une autre route, le composant précédemment affiché est détruit et le nouveau composant est chargé.

III. Naviguer entre les Vues

Maintenant que nous avons configuré nos routes et défini où les vues doivent s'afficher, voyons comment les utilisateurs peuvent naviguer entre elles. Angular offre deux méthodes principales pour la navigation : déclarative (via des attributs dans le template) et programmatique (via le code TypeScript).

1. Navigation Déclarative avec routerLink

La méthode la plus courante et la plus simple pour la navigation dans les templates est l'utilisation de la directive routerLink. Elle est généralement appliquée aux éléments <a> (ancres HTML).

<!-- src/app/app.component.html (extrait de la section <nav>) -->
<nav>
  <ul>
    <li>
      <!-- Navigue vers la route par défaut ('/') -->
      <a routerLink="/"
         routerLinkActive="active"
         [routerLinkActiveOptions]="{exact: true}">
        Accueil
      </a>
    </li>
    <li>
      <!-- Navigue vers la route '/about' -->
      <a routerLink="/about"
         routerLinkActive="active">
        À Propos
      </a>
    </li>
    <li>
      <!-- Navigue vers la route '/contact' -->
      <a routerLink="/contact"
         routerLinkActive="active">
        Contact
      </a>
    </li>
    <li>
      <!-- Navigue vers une route inexistante pour tester le 404 -->
      <a routerLink="/non-existent"
         routerLinkActive="active">
        Page Inconnue
      </a>
    </li>
  </ul>
</nav>

<!-- Ajoutez ce style simple dans votre src/app/app.component.css -->
<style>
  .active {
    font-weight: bold;
    color: blue;
  }
</style>

Explication :

  • routerLink="/chemin": C'est la forme la plus simple. Le routerLink est une directive Angular qui remplace le comportement par défaut de href pour intercepter la navigation et la gérer via le routeur. Vous pouvez passer une chaîne de caractères ou un tableau d'URL segments (utile pour les routes avec paramètres).
    • Exemple : [routerLink]="['/products', productId]"
  • routerLinkActive="active": Cette directive applique une ou plusieurs classes CSS (ici, active) à l'élément hôte (<a>) lorsque la route actuelle correspond à celle du routerLink. C'est très utile pour mettre en évidence le lien de la page sur laquelle l'utilisateur se trouve.
  • [routerLinkActiveOptions]="{exact: true}": Utilisé avec routerLinkActive, cette option est importante pour la route racine (/). Sans exact: true, routerLinkActive="active" sur / serait appliqué à toutes les routes, car toutes les routes "commencent" par /. exact: true garantit que la classe active n'est appliquée que si l'URL correspond exactement au routerLink.

2. Navigation Programmatique avec le Service Router

Parfois, vous avez besoin de déclencher une navigation depuis votre code TypeScript, par exemple après la soumission d'un formulaire, suite à une action de l'utilisateur qui n'est pas un simple clic sur un lien, ou après un traitement asynchrone. Pour cela, vous utilisez le service Router.

D'abord, vous devez injecter le service Router dans le constructeur de votre composant ou service.

// src/app/product-detail/product-detail.component.ts (Exemple de composant de détail de produit)
import { Component } from '@angular/core';
import { Router } from '@angular/router'; // 1. Importez le service Router

@Component({
  selector: 'app-product-detail',
  template: `
    <h2>Détail du Produit</h2>
    <p>Ceci est la page de détail d'un produit.</p>
    <button (click)="goToProducts()">Retour aux Produits</button>
    <button (click)="goToDashboard()">Aller au Tableau de Bord (avec Redirection)</button>
  `,
  styles: ['button { margin-right: 10px; }']
})
export class ProductDetailComponent {
  // 2. Injectez le service Router dans le constructeur
  constructor(private router: Router) {}

  goToProducts(): void {
    // 3. Utilisez la méthode navigate() pour naviguer vers une route
    // Le tableau représente les segments de l'URL
    this.router.navigate(['/products']); // Navigue vers /products
  }

  goToDashboard(): void {
    // navigate() est préférable pour les chemins absolus ou complexes
    this.router.navigate(['/dashboard', 'overview'], { queryParams: { from: 'product-detail' } });

    // navigateByUrl() est utile si vous avez déjà l'URL complète sous forme de string
    // this.router.navigateByUrl('/dashboard/overview?from=product-detail');
  }
}

Explication :

  • Injection du service Router: constructor(private router: Router) {} rend le service router disponible dans votre composant.
  • this.router.navigate(commands: any[], extras?: NavigationExtras):
    • Prend un tableau de segments d'URL. C'est flexible et idéal pour construire des chemins complexes, y compris ceux avec des paramètres (ex: ['/products', productId, 'edit']).
    • Peut prendre un deuxième argument NavigationExtras pour des options avancées comme queryParams (paramètres de requête), fragment, replaceUrl (remplacer l'entrée dans l'historique du navigateur), relativeTo (pour la navigation relative).
  • this.router.navigateByUrl(url: string | UrlTree, extras?: NavigationExtras):
    • Prend une URL complète sous forme de chaîne de caractères.
    • Utile lorsque vous avez déjà l'URL complète ou si vous récupérez l'URL d'une source externe.
    • Moins flexible pour la construction dynamique d'URL avec des paramètres.

Quand utiliser navigate() vs navigateByUrl() ?

  • Utilisez navigate() lorsque vous construisez l'URL à partir de segments et/ou de paramètres dynamiques. C'est la méthode la plus courante.
  • Utilisez navigateByUrl() lorsque vous avez déjà l'URL complète sous forme de chaîne de caractères (par exemple, un utilisateur a tapé une URL, ou elle vient d'une API).

IV. Gérer les Paramètres et Données des Routes

Les applications web ont souvent besoin de passer des données entre les vues. Par exemple, une page de liste de produits doit permettre de naviguer vers une page de détail d'un produit spécifique. Le Router Angular offre des mécanismes pour transmettre ces données via l'URL.

Il existe deux types principaux de paramètres : les paramètres de route (path parameters) et les paramètres de requête (query parameters).

1. Paramètres de Route (Path Parameters)

Les paramètres de route sont utilisés pour identifier des ressources spécifiques et font partie intégrante du chemin de l'URL. Par exemple, /products/123123 est l'ID du produit.

1. Définir la route avec un paramètre :

Dans votre app-routing.module.ts (ou le module de routage concerné) :

// src/app/app-routing.module.ts (Extrait)
const routes: Routes = [
  // ... autres routes
  { path: 'products/:id', component: ProductDetailComponent }, // ':id' est le paramètre de route
  // ... autres routes
];

Le : devant id indique que c'est un paramètre dynamique.

2. Naviguer vers cette route :

  • Déclarativement (avec routerLink) :
    <!-- Dans un composant ProductListComponent par exemple -->
    <a [routerLink]="['/products', product.id]">Voir Détails</a>
    <!-- Si product.id = 123, l'URL sera /products/123 -->
    
  • Programmatique (avec Router.navigate()) :
    // Dans un composant TypeScript
    import { Router } from '@angular/router';
    
    constructor(private router: Router) {}
    
    showProductDetail(productId: number): void {
      this.router.navigate(['/products', productId]);
    }
    

3. Accéder aux paramètres dans le composant ciblé :

Dans le ProductDetailComponent, vous utiliserez le service ActivatedRoute pour récupérer les paramètres.

// src/app/product-detail/product-detail.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router'; // Importez ActivatedRoute et ParamMap
import { switchMap } from 'rxjs/operators'; // Utile pour les Observables

@Component({
  selector: 'app-product-detail',
  template: `
    <h2>Détail du Produit : ID {{ productId }}</h2>
    <p *ngIf="productName">Nom du Produit : {{ productName }}</p>
    <p>Ceci est la page de détail pour le produit avec l'ID {{ productId }}.</p>
    <button (click)="goToProducts()">Retour à la liste des produits</button>
  `,
})
export class ProductDetailComponent implements OnInit {
  productId: string | null = null;
  productName: string = '';

  // Injectez ActivatedRoute dans le constructeur
  constructor(private route: ActivatedRoute /*, private router: Router (si besoin de navigation) */) {}

  ngOnInit(): void {
    // Méthode 1: Utiliser snapshot (si le composant n'est pas réutilisé pour des IDs différents)
    // Utile quand le composant est créé et détruit à chaque navigation
    this.productId = this.route.snapshot.paramMap.get('id');
    console.log('ID du produit (snapshot):', this.productId);
    this.fetchProductDetails(this.productId);


    // Méthode 2: S'abonner à paramMap (recommandé pour la réactivité)
    // Le paramMap est un Observable. Utilisez-le si les paramètres peuvent changer sans que le composant ne soit détruit (ex: navigation vers /products/1 puis /products/2 sur le même composant)
    this.route.paramMap.subscribe((params: ParamMap) => {
      this.productId = params.get('id'); // 'id' doit correspondre au nom défini dans la route (:id)
      console.log('ID du produit (Observable):', this.productId);
      this.fetchProductDetails(this.productId); // Recharger les détails du produit si l'ID change
    });
  }

  private fetchProductDetails(id: string | null): void {
    if (id) {
      // Simuler la récupération de données
      this.productName = `Produit ${id}`;
      // Normalement, ici vous feriez un appel à un service (ex: this.productService.getProduct(id))
    }
  }

  // Exemple de fonction pour revenir à la liste des produits
  // goToProducts(): void {
  //   this.router.navigate(['/products']);
  // }
}

Explication :

  • ActivatedRoute: Un service injecté qui contient des informations sur la route activée pour ce composant.
  • snapshot.paramMap.get('id'): Le snapshot contient l'état initial des paramètres de la route. C'est suffisant si vous êtes sûr que les paramètres ne changeront pas pendant la durée de vie du composant (c'est-à-dire, si le composant est toujours recréé pour un nouvel ID).
  • paramMap.subscribe(...): paramMap est un Observable. Il est recommandé de s'y abonner si le composant peut être réutilisé lorsque seuls les paramètres de l'URL changent (par exemple, passer de /products/1 à /products/2 sans quitter le ProductDetailComponent). Cela garantit que votre composant réagit aux changements de paramètres.

2. Paramètres de Requête (Query Parameters)

Les paramètres de requête sont des paires clé-valeur ajoutées à la fin de l'URL, après un ?. Ils sont souvent utilisés pour des options de filtrage, de tri, ou pour passer des informations facultatives qui ne font pas partie de l'identification unique de la ressource. Exemple : /products?category=electronics&sort=price.

1. Naviguer avec des paramètres de requête :

Les paramètres de requête ne sont pas définis dans l'objet routes. Ils sont ajoutés lors de la navigation.

// src/app/product-list/product-list.component.ts (Exemple pour une page de liste)
import { Component } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-product-list',
  template: `
    <h2>Liste des Produits</h2>
    <p>Filtres appliqués : Catégorie: {{ category || 'N/A' }}, Tri: {{ sortBy || 'N/A' }}</p>
    <button (click)="filterProducts('electronics', 'price-asc')">Filtrer par Electronique & Prix</button>
    <button (click)="clearFilters()">Effacer les filtres</button>
  `,
  styles: ['button { margin-right: 10px; margin-bottom: 10px; }']
})
export class ProductListComponent {
  category: string | null = null;
  sortBy: string | null = null;

  constructor(private router: Router, private route: ActivatedRoute) {}

  ngOnInit(): void {
    // S'abonner aux changements des paramètres de requête
    this.route.queryParamMap.subscribe(params => {
      this.category = params.get('category');
      this.sortBy = params.get('sort');
      console.log('Paramètres de requête mis à jour:', this.category, this.sortBy);
      // Ici, vous pouvez déclencher le chargement des produits avec les filtres
    });
  }

  filterProducts(category: string, sortBy: string): void {
    // Naviguer vers la route actuelle, mais ajouter/modifier les queryParams
    this.router.navigate([], {
      relativeTo: this.route, // Garde le chemin de base actuel
      queryParams: { category: category, sort: sortBy },
      queryParamsHandling: 'merge' // Conserve les queryParams existants et ajoute/modifie ceux-ci
      // 'preserve': conserve tous les queryParams existants
      // 'merge': fusionne les nouveaux queryParams avec les existants
      // null (par défaut) ou '': remplace tous les queryParams
    });
  }

  clearFilters(): void {
    // Naviguer vers la route actuelle en supprimant tous les queryParams
    this.router.navigate([], {
      relativeTo: this.route,
      queryParams: null // Supprime tous les paramètres de requête
    });
  }
}

Explication :

  • Navigation : La méthode navigate() est utilisée avec un tableau vide ([]) comme premier argument pour indiquer que nous restons sur la route actuelle, mais nous ajoutons l'objet queryParams dans le deuxième argument (NavigationExtras).
    • relativeTo: this.route: Ceci est crucial. Il indique que la navigation doit être relative à la route actuellement activée. Sans cela, navigate([]) vous ramènerait à la racine (/).
    • queryParamsHandling: 'merge': Cette option est très utile.
      • 'merge': Ajoute de nouveaux paramètres de requête aux existants ou remplace ceux qui ont le même nom.
      • 'preserve': Conserve tous les paramètres de requête existants et ignore ceux que vous essayez d'ajouter.
      • Par défaut (ou si omis), tous les paramètres de requête existants seraient supprimés à moins d'être explicitement inclus.
  • Accès aux paramètres : Comme pour les paramètres de route, vous utilisez ActivatedRoute mais cette fois, vous vous abonnez à queryParamMap pour obtenir les valeurs des paramètres de requête.

V. Concepts Avancés (Aperçu)

Le Router Angular est incroyablement riche en fonctionnalités. Voici un bref aperçu de quelques concepts avancés qui améliorent la performance et la sécurité de vos applications.

1. Chargement Paresseux (Lazy Loading)

Pour les grandes applications, charger tout le code de l'application dès le démarrage peut entraîner des temps de chargement initiaux importants. Le chargement paresseux (Lazy Loading) permet de charger des modules de fonctionnalités uniquement lorsque l'utilisateur y accède.

  • Avantage : Réduit la taille du bundle initial de l'application, ce qui améliore les performances et l'expérience utilisateur, en particulier sur les connexions lentes.
  • Fonctionnement : Au lieu de spécifier directement un component dans la définition de la route, vous utilisez loadChildren pour pointer vers le module que vous souhaitez charger de manière paresseuse.
// src/app/app-routing.module.ts (Extrait)
const routes: Routes = [
  // ...
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
  },
  // ...
];

Lorsque l'utilisateur navigue vers /admin, le module AdminModule et tous ses composants et services sont chargés en arrière-plan.

2. Gardiens de Route (Route Guards)

Les gardiens de route sont des classes que vous implémentez pour contrôler l'accès aux routes, la capacité de naviguer vers ou de quitter une route, ou même le chargement d'un module paresseux.

  • Utilité : Gérer l'authentification, l'autorisation, la confirmation de sauvegarde de formulaires non enregistrés, etc.
  • Types courants :
    • CanActivate : Décide si une route peut être activée (si l'utilisateur peut y naviguer).
    • CanDeactivate : Décide si une route peut être désactivée (si l'utilisateur peut la quitter).
    • CanLoad : Décide si un module paresseux peut être chargé du tout.

Exemple d'application d'un gardien CanActivate :

// src/app/app-routing.module.ts (Extrait)
import { AuthGuard } from './auth.guard'; // Supposons que vous avez un AuthGuard

const routes: Routes = [
  // ...
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
  // ...
];

Ici, DashboardComponent ne sera activé que si AuthGuard retourne true.


Conclusion : Maîtriser le Flux de l'Application

Le Router Angular est bien plus qu'un simple gestionnaire d'URL ; c'est un pilier central du développement d'applications Single Page Applications (SPAs) modernes et robustes. Il vous donne le pouvoir de créer des expériences utilisateur dynamiques et fluides, en donnant l'illusion de pages distinctes sans les inconvénients des rechargements complets.

Au cours de cette leçon, vous avez acquis les compétences fondamentales pour :

  • Comprendre l'importance du routage dans le contexte des SPAs Angular.
  • Initialiser et configurer votre module de routage principal.
  • Définir des routes claires et logiques, en associant des chemins URL à des composants Angular spécifiques.
  • Utiliser <router-outlet> comme point d'ancrage dynamique pour vos vues routées.
  • Naviguer efficacement dans votre application, que ce soit de manière déclarative avec routerLink ou de manière programmatique via le service Router.
  • Transmettre et récupérer des données entre les vues en utilisant les paramètres de route (path parameters) et les paramètres de requête (query parameters).

La maîtrise de ces concepts est essentielle pour créer des applications Angular complexes et performantes. En explorant davantage les concepts avancés comme le chargement paresseux et les gardiens de route, vous pourrez optimiser la performance et la sécurité de vos applications, offrant ainsi une expérience utilisateur encore plus enrichissante. Le Router Angular est votre allié pour sculpter le flux de navigation de votre application avec précision et agilité.