Comment transmettre des données dans les composants routés Angular : guide complet en TypeScript
\n\nChaque développeur qui commence à travailler avec Angular se retrouve tôt ou tard confronté à la question : « Comment transmettre des données d'un composant à un autre via le routeur ? ». Sur Stack Overflow, cette question a recueilli des milliers de vues — et ce n'est pas un hasard. Contrairement aux composants parent-enfant classiques, où il suffit d'utiliser @Input() et @Output(), le routage dans Angular ajoute ses propres complexités.
Dans cet article, nous allons examiner 5 méthodes éprouvées pour transmettre des données dans les Angular routed components. Vous apprendrez quand utiliser chaque méthode et obtiendrez des exemples prêts à l'emploi en TypeScript. C'est parti !
\n\nPourquoi ne peut-on pas simplement transmettre des données via @Input ?
\n\nBeaucoup de débutants essaient de faire ceci :
\n\n// ❌ Cela ne fonctionne pas\n<router-outlet [someData]="data"></router-outlet>\n\nLe routeur Angular crée les composants dynamiquement. router-outlet est une directive, pas un élément de template. Par conséquent, la transmission directe de données via des attributs est impossible. Mais il existe des solutions de contournement — et elles sont même plus pratiques !
Méthode 1 : Utilisation de Router State (la plus simple)
\n\nLa méthode la plus intuitive consiste à transmettre des données via l'objet state lors de la navigation. Cette méthode est apparue dans Angular 7+ et fonctionne « prête à l'emploi ».
Comment cela fonctionne
\n\nVous transmettez un objet avec des données lors de l'appel à router.navigate() ou via routerLink.
// Component A — expéditeur\nimport { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\n@Component({\n selector: 'app-user-list',\n template: `\n <button (click)="goToDetails()">Ouvrir l'utilisateur</button>\n `\n})\nexport class UserListComponent {\n constructor(private router: Router) {}\n\n goToDetails() {\n this.router.navigate(['/user', 42], {\n state: { name: 'Ivan Petrov', role: 'admin' }\n });\n }\n}\n\n// Component B — destinataire\nimport { Component, OnInit } from '@angular/core';\nimport { Router } from '@angular/router';\n\n@Component({\n selector: 'app-user-details',\n template: `\n <div *ngIf="userData">\n <h2>{{ userData.name }}</h2>\n <p>Rôle : {{ userData.role }}</p>\n </div>\n `\n})\nexport class UserDetailsComponent implements OnInit {\n userData: any;\n\n constructor(private router: Router) {\n // Récupération des données depuis l'historique de navigation\n this.userData = this.router.getCurrentNavigation()?.extras?.state;\n }\n\n ngOnInit() {\n // Méthode alternative — via history.state\n if (!this.userData) {\n this.userData = history.state;\n }\n }\n}\n\nAvantages et inconvénients
\n- \n
- ✅ Simplicité de mise en œuvre \n
- ✅ Les données ne sont pas visibles dans l'URL \n
- ✅ Fonctionne avec tous les types de données (objets, tableaux) \n
- ❌ Les données sont perdues lors du rechargement de la page \n
- ❌ Ne fonctionne pas lors d'un accès direct par URL \n
Quand l'utiliser : pour transmettre des données temporaires qui ne sont pas critiques lors du rechargement (par exemple, messages flash, filtres).
\n\nMéthode 2 : Route Resolver (pour le préchargement des données)
\n\nSi vous devez charger des données avant que le composant ne s'affiche, utilisez Angular Resolver. C'est un service qui résout les données avant l'activation de la route.
\n\nCréation du Resolver
\n\n// user.resolver.ts\nimport { Injectable } from '@angular/core';\nimport { Resolve, ActivatedRouteSnapshot } from '@angular/router';\nimport { Observable, of } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class UserResolver implements Resolve<any> {\n resolve(route: ActivatedRouteSnapshot): Observable<any> {\n const userId = route.paramMap.get('id');\n // Im