Un guide complet du routage en angulaire
Publié: 2022-03-10Au cas où vous ne seriez pas encore très familier avec Angular 7, j'aimerais vous rapprocher de tout ce que cet impressionnant framework frontal a à offrir. Je vais vous guider à travers une application de démonstration angulaire qui montre différents concepts liés au routeur, tels que :
- La prise du routeur,
- Routes et chemins,
- La navigation.
Je vais également vous montrer comment utiliser Angular CLI v7 pour générer un projet de démonstration où nous utiliserons le routeur Angular pour implémenter le routage et la navigation. Mais d'abord, permettez-moi de vous présenter Angular et de passer en revue certaines des nouvelles fonctionnalités importantes de sa dernière version.
Présentation d'Angular 7
Angular est l'un des frameworks frontaux les plus populaires pour la création d'applications Web côté client pour le Web mobile et de bureau. Il suit une architecture basée sur des composants où chaque composant est un morceau de code isolé et réutilisable qui contrôle une partie de l'interface utilisateur de l'application.
Un composant dans Angular est une classe TypeScript décorée avec le décorateur @Component
. Il a un modèle attaché et des feuilles de style CSS qui forment la vue du composant.
Angular 7, la dernière version d'Angular a été récemment publiée avec de nouvelles fonctionnalités, en particulier dans l'outillage CLI et les performances, telles que :
- Invites CLI : une commande courante telle que
ng add
etng new
peut désormais inviter l'utilisateur à choisir les fonctionnalités à ajouter à un projet, telles que le format de routage et de feuilles de style, etc. - Ajout du défilement à Angular Material CDK (Component DevKit).
- Ajout de la prise en charge du glisser-déposer à Angular Material CDK.
- Par défaut, les projets utilisent également des forfaits budgétaires qui avertiront les développeurs lorsque leurs applications dépassent les limites de taille. Par défaut, des avertissements sont émis lorsque la taille dépasse 2 Mo et des erreurs à 5 Mo. Vous pouvez également modifier ces limites dans votre fichier
angular.json
. etc.
Présentation du routeur angulaire
Angular Router est un puissant routeur JavaScript construit et maintenu par l'équipe principale d'Angular qui peut être installé à partir du package @angular/router
. Il fournit une bibliothèque de routage complète avec la possibilité d'avoir plusieurs sorties de routeur, différentes stratégies de correspondance de chemin, un accès facile aux paramètres de routage et des gardes de routage pour protéger les composants contre les accès non autorisés.
Le routeur angulaire est un élément central de la plate-forme angulaire. Il permet aux développeurs de créer des applications à page unique avec plusieurs vues et de permettre la navigation entre ces vues.
Voyons maintenant plus en détail les concepts essentiels du routeur.
Le Routeur-Outlet
Router-Outlet
est une directive disponible dans la bibliothèque du routeur où le routeur insère le composant correspondant en fonction de l'URL du navigateur actuel. Vous pouvez ajouter plusieurs prises dans votre application Angular, ce qui vous permet de mettre en œuvre des scénarios de routage avancés.
<router-outlet></router-outlet>
Tout composant qui est mis en correspondance par le routeur le rendra comme un frère de la prise du routeur.
Itinéraires et chemins
Les routes sont des définitions (objets) composées d'au moins un chemin et des attributs d'un composant (ou d'un chemin redirectTo). Le chemin fait référence à la partie de l'URL qui détermine une vue unique à afficher, et le composant fait référence au composant angulaire qui doit être associé à un chemin. Sur la base d'une définition de route que nous fournissons (via une méthode statique RouterModule.forRoot(routes)
), le routeur est capable de diriger l'utilisateur vers une vue spécifique.
Chaque Route
mappe un path
d'URL vers un composant.
Le chemin peut être vide, ce qui indique le chemin par défaut d'une application et c'est généralement le début de l'application.
Le chemin peut prendre une chaîne générique ( **
). Le routeur sélectionnera cette route si l'URL demandée ne correspond à aucun chemin pour les routes définies. Cela peut être utilisé pour afficher une vue "Introuvable" ou rediriger vers une vue spécifique si aucune correspondance n'est trouvée.
Voici un exemple de parcours :
{ path: 'contacts', component: ContactListComponent}
Si cette définition de route est fournie à la configuration du routeur, le routeur affichera ContactListComponent
lorsque l'URL du navigateur pour l'application Web devient /contacts
.
Stratégies d'appariement d'itinéraire
Le routeur angulaire fournit différentes stratégies de correspondance de route. La stratégie par défaut consiste simplement à vérifier si l'URL du navigateur actuel est précédée du chemin .
Par exemple notre parcours précédent :
{ path: 'contacts', component: ContactListComponent}
Peut aussi s'écrire :
{ path: 'contacts',pathMatch: 'prefix', component: ContactListComponent}
L'attribut patchMath
spécifie la stratégie de correspondance. Dans ce cas, c'est le préfixe qui est la valeur par défaut.
La deuxième stratégie de correspondance est full . Lorsqu'il est spécifié pour une route, le routeur vérifiera si le chemin est exactement égal au chemin de l'URL du navigateur actuel :
{ path: 'contacts',pathMatch: 'full', component: ContactListComponent}
Paramètres de route
La création d'itinéraires avec des paramètres est une fonctionnalité courante dans les applications Web. Angular Router vous permet d'accéder aux paramètres de différentes manières :
- En utilisant le service ActivatedRoute,
- Utilisation de l'observable ParamMap disponible à partir de la v4.
Vous pouvez créer un paramètre de route à l'aide de la syntaxe deux- points . Voici un exemple de route avec un paramètre id :
{ path: 'contacts/:id', component: ContactDetailComponent}
Gardes de route
Un garde de route est une fonctionnalité du routeur angulaire qui permet aux développeurs d'exécuter une logique lorsqu'une route est demandée, et sur la base de cette logique, il autorise ou refuse l'accès de l'utilisateur à la route. Il est couramment utilisé pour vérifier si un utilisateur est connecté et dispose de l'autorisation avant de pouvoir accéder à une page.
Vous pouvez ajouter un garde de route en implémentant l'interface CanActivate
disponible dans le package @angular/router
et étendre la méthode canActivate()
qui contient la logique pour autoriser ou refuser l'accès à la route. Par exemple, le garde suivant autorisera toujours l'accès à une route :
class MyGuard implements CanActivate { canActivate() { return true; } }
Vous pouvez ensuite protéger une route avec le garde en utilisant l'attribut canActivate
:
{ path: 'contacts/:id, canActivate:[MyGuard], component: ContactDetailComponent}
Directive Navigation
Le routeur angulaire fournit la directive routerLink
pour créer des liens de navigation. Cette directive prend le chemin associé au composant vers lequel naviguer. Par exemple:
<a [routerLink]="'/contacts'">Contacts</a>
Prises multiples et routes auxiliaires
Angular Router prend en charge plusieurs prises dans la même application.
Un composant a une route principale associée et peut avoir des routes auxiliaires. Les itinéraires auxiliaires permettent aux développeurs de parcourir plusieurs itinéraires en même temps.
Pour créer une route auxiliaire, vous aurez besoin d'une prise de routeur nommée où le composant associé à la route auxiliaire sera affiché.
<router-outlet></router-outlet> <router-outlet name="outlet1"></router-outlet>
- La prise sans nom est la prise principale.
- Toutes les prises doivent avoir un nom, à l'exception de la prise principale.
Vous pouvez ensuite spécifier la prise où vous souhaitez rendre votre composant à l'aide de l'attribut outlet :
{ path: "contacts", component: ContactListComponent, outlet: "outlet1" }
Création d'un projet de démonstration Angular 7
Dans cette section, nous verrons un exemple pratique de la configuration et de l'utilisation du routeur angulaire. Vous pouvez voir la démo en direct que nous allons créer et le référentiel GitHub du projet.
Installation de la CLI angulaire v7
Angular CLI nécessite Node 8.9+ , avec NPM 5.5.1+ . Vous devez vous assurer que ces exigences sont installées sur votre système, puis exécutez la commande suivante pour installer la dernière version d'Angular CLI :
$ npm install -g @angular/cli
Cela installera la CLI angulaire globalement.
Remarque : Vous pouvez utiliser sudo
pour installer des packages globalement, en fonction de votre configuration npm.
Création d'un projet angulaire 7
La création d'un nouveau projet se fait en une seule commande, il vous suffit d'exécuter la commande suivante :
$ ng new angular7-router-demo
La CLI vous demandera si vous souhaitez ajouter un routage (tapez N
pour Non car nous verrons comment ajouter un routage manuellement) et quel format de feuille de style souhaitez-vous utiliser, choisissez CSS, la première option puis appuyez sur Enter
. La CLI créera une structure de dossiers avec les fichiers nécessaires et installera les dépendances requises du projet.
Créer un faux service back-end
Comme nous n'avons pas de vrai back-end avec lequel interagir, nous allons créer un faux back-end en utilisant la bibliothèque angular-in-memory-web-api
qui est une API web en mémoire pour les démos et les tests angulaires qui émule les opérations CRUD sur une API REST.
Cela fonctionne en interceptant les requêtes HttpClient
envoyées au serveur distant et en les redirigeant vers un magasin de données local en mémoire que nous devons créer.
Pour créer un faux back-end, nous devons suivre les étapes suivantes :
- Tout d'abord, nous installons le module
angular-in-memory-web-api
, - Ensuite, nous créons un service qui renvoie de fausses données,
- Enfin, configurez l'application pour utiliser le faux back-end.
Dans votre terminal, exécutez la commande suivante pour installer le module angular-in-memory-web-api
à partir de npm :
$ npm install --save angular-in-memory-web-api
Ensuite, générez un service back-end en utilisant :
$ ng gs backend
Ouvrez le fichier src/app/backend.service.ts
et importez InMemoryDbService
depuis le module angular-in-memory-web-api
:
import {InMemoryDbService} from 'angular-in-memory-web-api'
La classe de service doit implémenter InMemoryDbService
, puis remplacer la méthode createDb()
:
@Injectable({ providedIn: 'root' }) export class BackendService implements InMemoryDbService{ constructor() { } createDb(){ let contacts = [ { id: 1, name: 'Contact 1', email: '[email protected]' }, { id: 2, name: 'Contact 2', email: '[email protected]' }, { id: 3, name: 'Contact 3', email: '[email protected]' }, { id: 4, name: 'Contact 4', email: '[email protected]' } ]; return {contacts}; } }
Nous créons simplement un tableau de contacts et les renvoyons. Chaque contact doit avoir un identifiant.
Enfin, nous devons simplement importer InMemoryWebApiModule
dans le fichier app.module.ts
et fournir notre faux service back-end.
import { InMemoryWebApiModule } from “angular-in-memory-web-api”; import { BackendService } from “./backend.service”; /* ... */ @NgModule({ declarations: [ /*...*/ ], imports: [ /*...*/ InMemoryWebApiModule.forRoot(BackendService) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Créez ensuite un ContactService
qui encapsule le code pour travailler avec les contacts :
$ ng gs contact
Ouvrez le fichier src/app/contact.service.ts
et mettez-le à jour pour qu'il ressemble au code suivant :
import { Injectable } from '@angular/core'; import { HttpClient } from “@angular/common/http”; @Injectable({ providedIn: 'root' }) export class ContactService { API_URL: string = "/api/"; constructor(private http: HttpClient) { } getContacts(){ return this.http.get(this.API_URL + 'contacts') } getContact(contactId){ return this.http.get(`${this.API_URL + 'contacts'}/${contactId}`) } }
Nous avons ajouté deux méthodes :
-
getContacts()
Pour obtenir tous les contacts. -
getContact()
Pour obtenir un contact par identifiant.
Vous pouvez définir l' API_URL
sur n'importe quelle URL puisque nous n'allons pas utiliser un vrai back-end. Toutes les requêtes seront interceptées et envoyées au back-end en mémoire.
Création de nos composants angulaires
Avant de voir comment utiliser les différentes fonctionnalités du routeur, créons d'abord un ensemble de composants dans notre projet.
Rendez-vous sur votre terminal et exécutez les commandes suivantes :
$ ng gc contact-list $ ng gc contact-detail
Cela générera deux composants ContactListComponent
et ContactDetailComponent
et les ajoutera au module principal de l'application.
Configuration du routage
Dans la plupart des cas, vous utiliserez la CLI angulaire pour créer des projets avec une configuration de routage, mais dans ce cas, nous l'ajouterons manuellement afin que nous puissions avoir une meilleure idée du fonctionnement du routage dans Angular.
Ajout du module de routage
Nous devons ajouter AppRoutingModule
qui contiendra nos itinéraires d'application et une sortie de routeur où Angular insérera le composant actuellement correspondant en fonction de l'URL actuelle du navigateur.
On verra:
- Comment créer un module angulaire pour le routage et l'importer ;
- Comment ajouter des itinéraires à différents composants ;
- Comment ajouter la prise du routeur.
Tout d'abord, commençons par créer un module de routage dans un fichier app-routing.module.ts
. Dans le src/app
créez le fichier en utilisant :
$ cd angular7-router-demo/src/app $ touch app-routing.module.ts
Ouvrez le fichier et ajoutez le code suivant :
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = []; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
Nous commençons par importer le NgModule
à partir du package @angular/core
qui est un décorateur TypeScript utilisé pour créer un module Angular.
Nous importons également les classes RouterModule
et Routes
du package @angular/router
. RouterModule
fournit des méthodes statiques telles que RouterModule.forRoot()
pour transmettre un objet de configuration au routeur.
Ensuite, nous définissons un tableau de routes
constantes de type Routes
qui sera utilisé pour contenir les informations de chaque route.
Enfin, nous créons et exportons un module appelé AppRoutingModule
(vous pouvez l'appeler comme vous voulez) qui est simplement une classe TypeScript décorée avec le décorateur @NgModule
qui prend un objet de méta-information. Dans l'attribut imports
de cet objet, nous appelons la méthode statique RouterModule.forRoot(routes)
avec le tableau routes en paramètre. Dans le tableau exports
nous ajoutons le RouterModule
.
Importation du module de routage
Ensuite, nous devons importer ce routage de module dans le module principal de l'application qui se trouve dans le fichier src/app/app.module.ts
:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Nous importons le AppRoutingModule
depuis ./app-routing.module
et nous l'ajoutons dans le tableau imports
du module principal.
Ajout de la prise du routeur
Enfin, nous devons ajouter la prise du routeur. Ouvrez le fichier src/app/app.component.html
qui contient le modèle d'application principal et ajoutez le composant <router-outlet>
:
<router-outlet></router-outlet>
C'est là que le routeur angulaire rendra le composant qui correspond au chemin du navigateur actuel.
Ce sont toutes les étapes que nous devons suivre pour configurer manuellement le routage dans un projet Angular.
Création d'itinéraires
Ajoutons maintenant des routes à nos deux composants. Ouvrez le fichier src/app/app-routing.module.ts
et ajoutez les routes suivantes au tableau routes
:
const routes: Routes = [ {path: 'contacts' , component: ContactListComponent}, {path: 'contact/:id' , component: ContactDetailComponent} ];
Assurez-vous d'importer les deux composants dans le module de routage :
import { ContactListComponent } from './contact-list/contact-list.component'; import { ContactDetailComponent } from './contact-detail/contact-detail.component';
Nous pouvons maintenant accéder aux deux composants à partir des chemins /contacts
et contact/:id
.
Ajouter des liens de navigation
Ajoutons ensuite des liens de navigation à notre modèle d'application à l'aide de la directive routerLink
. Ouvrez le src/app/app.component.html
et ajoutez le code suivant en haut de la prise du routeur :
<h2><a [routerLink] = "'/contacts'">Contacts</a></h2>
Ensuite, nous devons afficher la liste des contacts dans ContactListComponent
. Ouvrez le src/app/contact-list.component.ts
puis ajoutez le code suivant :
import { Component, OnInit } from '@angular/core'; import { ContactService } from '../contact.service'; @Component({ selector: 'app-contact-list', templateUrl: './contact-list.component.html', styleUrls: ['./contact-list.component.css'] }) export class ContactListComponent implements OnInit { contacts: any[] = []; constructor(private contactService: ContactService) { } ngOnInit() { this.contactService.getContacts().subscribe((data : any[])=>{ console.log(data); this.contacts = data; }) } }
Nous créons un tableau de contacts
pour contenir les contacts. Ensuite, nous injectons ContactService
et nous appelons la méthode getContacts()
de l'instance (sur l'événement de cycle de vie ngOnInit
) pour obtenir des contacts et les affecter au tableau de contacts
.
Ouvrez ensuite le fichier src/app/contact-list/contact-list.component.html
et ajoutez :
<table> <tr> <th>Name</th> <th>Email</th> <th>Actions</th> </tr> <tr *ngFor="let contact of contacts" > <td>{{ contact.name }}</td> <td>{{ contact.email }}</td> <td> <a [routerLink]="['/contact', contact.id]">Go to details</a> </td> </tr> </table>
Nous parcourons les contacts et affichons le nom et l'e-mail de chaque contact. Nous créons également un lien vers le composant de détails de chaque contact à l'aide de la directive routerLink
.
Voici une capture d'écran du composant :
Lorsque nous cliquons sur le lien Aller aux détails , cela nous mènera à ContactDetailsComponent
. La route a un paramètre id
, voyons comment nous pouvons y accéder depuis notre composant.
Ouvrez le fichier src/app/contact-detail/contact-detail.component.ts
et modifiez le code pour qu'il ressemble au code suivant :
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ContactService } from '../contact.service'; @Component({ selector: 'app-contact-detail', templateUrl: './contact-detail.component.html', styleUrls: ['./contact-detail.component.css'] }) export class ContactDetailComponent implements OnInit { contact: any; constructor(private contactService: ContactService, private route: ActivatedRoute) { } ngOnInit() { this.route.paramMap.subscribe(params => { console.log(params.get('id')) this.contactService.getContact(params.get('id')).subscribe(c =>{ console.log(c); this.contact = c; }) }); } }
Nous injectons ContactService
et ActivatedRoute
dans le composant. Dans l'événement de cycle de vie ngOnInit()
, nous récupérons le paramètre id qui sera transmis à partir de la route et l'utilisons pour obtenir les détails du contact que nous attribuons à un objet contact
.
Ouvrez le fichier src/app/contact-detail/contact-detail.component.html
et ajoutez :
<h1> Contact # {{contact.id}}</h1> <p> Name: {{contact.name}} </p> <p> Email: {{contact.email}} </p>
Lorsque nous visitons notre application pour la première fois à partir de 127.0.0.1:4200/
, l'outlet ne restitue aucun composant. Redirigeons donc le chemin vide vers le chemin des contacts
en ajoutant la route suivante au tableau routes :
{path: '', pathMatch: 'full', redirectTo: 'contacts'}
Nous voulons faire correspondre le chemin vide exact, c'est pourquoi nous spécifions la stratégie de correspondance complète .
Conclusion
Dans ce didacticiel, nous avons vu comment utiliser le routeur angulaire pour ajouter le routage et la navigation dans notre application. Nous avons vu différents concepts comme la sortie du routeur, les itinéraires et les chemins et nous avons créé une démo pour montrer pratiquement les différents concepts. Vous pouvez accéder au code à partir de ce référentiel.