Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. JavaScript et Angular
  3. Routage
Extrait - JavaScript et Angular Des bases du langage au développement d'une application web
Extraits du livre
JavaScript et Angular Des bases du langage au développement d'une application web
1 avis
Revenir à la page d'achat du livre

Routage

Commandes Git

Les commandes GIT suivantes permettent d’accéder au code source des chapitres précédents :

cd C:\ 
git clone https://github.com/EditionsENI/JavaScriptEtAngular.git 
cd C:\JavaScriptEtAngular\Angular 
git checkout chapitre15 
code . 

Introduction

Depuis 1993, les applications web ont bien changé. Elles contiennent à présent un nombre très important de données à afficher et un nombre toujours croissant d’utilisateurs habitués à une réaction instantanée au clic de la souris. À l’époque, chaque page était affichée entièrement à chaque rechargement du navigateur, ce qui entraînait des surcharges réseau et système et contribuait aux mauvaises performances de l’application en général.

Le concept d’application web monopage (ou SPA : Single Page Application) a permis d’augmenter l’expérience utilisateur. L’application n’est composée que d’une seule page qui charge les éléments à la demande.

L’application est accessible sur tablettes, téléphones intelligents et ordinateurs, elle répond au quart de tour puisqu’elle utilise les ressources clientes, et non pas serveur, et la consommation réseau est réduite.

Puisque l’objectif est de ne pas recharger la page à chaque demande utilisateur, le développeur doit trouver un moyen de faire correspondre une adresse internet à une classe JavaScript qui se chargera de modifier l’apparence de la page principale en conséquence.

Le routage d’Angular va permettre...

Angular CLI et le routage

Lors de la génération d’un nouveau projet Angular, Angular CLI propose l’utilisation du système de routage d’Angular. La réponse positive à cette question entraîne trois modifications majeures par rapport à une application qui a répondu non :

  • L’ajout d’une balise HTML dans le fichier index.html :<base href=’/’>.

  • La création d’un fichier app-routing.module.ts qui contient une classe AppRoutingModule

  • L’ajout dans le fichier app-module.ts de l’import du module AppRoutingModule.

Bien entendu, si le développeur souhaite ajouter du routage à un projet existant, ces trois modifications peuvent être effectuées manuellement.

href != routerLink

Comme l’application est monopage, l’ensemble des liens hypertextes est à modifier. En effet, plutôt qu’utiliser le comportement HTML classique d’une balise <a href="">, elle va utiliser la directive Angular routerLink. Visuellement, le résultat est le même, mais la directive modifie le DOM alors que href recharge la page.

<a routerLink="/url"> </a> 

Au clic sur le lien, Angular parcourt le tableau à la recherche d’une occurrence de routes et effectue la navigation vers le composant chargé du rendu. Si href et routerLink sont mis en concurrence, la différence en termes de performance est visible même à l’œil nu.

<!--C:\JavaScriptEtAngular\Angular\monProjetAngular\src\app\ 
app.components. html --> 
<div style="text-align:center"> 
    <img width="300" alt="Angular Logo" 
        src="data:image/
svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv 
MjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9 
IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIz 
MGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMw 
MDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDmuNyAxNC4yLTEyMy4x 
TDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1 
Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgz...

app-routing.module.ts

Le fichier app-routing.module.ts est une classe TypeScript exportée. Elle contient un tableau de routes nommé routes.

const routes: Routes = [ ]; 

Une route est un objet JavaScript qui contient une URL et un composant.

{path : 'url', component : unComposant} 

Finalement, un tableau de routes est un simple tableau d’objets JavaScript.

ng generate component composants/unComposant 
ng generate component composants/unAutre 

// C:\JavaScriptEtAngular\Angular/src/app-routing.module.ts 
import { NgModule } from '@angular/core';  
import { Routes, 
RouterModule } from '@angular/router'; 
 
import { UnComposantComponent } from '../app/composants/un- 
composant/un-composant.component'; 
import { UnAutreComponent } from '../app/composants/un-autre/ 
un-autre.component'; 
 
 
 
const routes: Routes = [ 
 {path: 'abc', component: UnComposantComponent}, 
 {path: 'xyz', component: UnAutreComponent}, 
]; 
 
 
@NgModule({ 
 imports: [RouterModule.forRoot(routes)], 
 exports: [RouterModule] 
}) 
export class AppRoutingModule { } 

Si l’utilisateur entre l’adresse http://www.monSiteWeb/abc, alors l’application utilisera le composant...

Routes

1. Route joker

À ce stade, l’application ne fournit de rendu correct que lorsque les URL /, /abc et /xyz sont entrées par l’utilisateur. N’importe quelles autres URL (/azertyuiop par exemple) provoque une erreur puisque le module de routage d’Angular ne trouve aucune correspondance dans son tableau de routes. L’erreur n’est pas visible dans le navigateur web, mais beaucoup plus bavarde dans la console.

images/15RI02.png

Navigation vers une route non gérée http://localhost:4200/azertyuiop

Afin de pallier ce genre de problème, Angular permet l’utilisation d’une route joker symbolisée par deux astérisques (**). C’est un petit peu la ’’route poubelle’’ : elle accepte toutes les URL. La route joker doit pratiquement toujours être la dernière des routes puisque, si elle était la première, il y aurait correspondance et Angular n’évaluerait jamais les autres.

2. Routes paramétrées

Parfois, le développeur a besoin de passer des paramètres dans l’URL afin d’agir en conséquence dans le composant ou le gabarit. Cela peut être utile notamment lorsqu’un composant affiche une liste d’éléments et qu’un clic permet d’en voir un seul en détail. Bien entendu, il doit exister un numéro unique permettant d’identifier cet élément puisque c’est cet identifiant qui sera utilisé. 

Ici, la liste d’éléments est un tableau d’objets JavaScript, mais l’appel à une API est tout à fait possible. Ces appels seront étudiés dans le chapitre Programmation réactive.

// C:\JavaScriptEtAngular\Angular\monProjetAngular\src\app\ 
composants\c15\c15.components.ts 
import { Component, OnInit } from '@angular/core'; 
 
@Component({ 
 selector: 'app-c15', 
 templateUrl: './c15.component.html', 
 styleUrls: ['./c15.component.css'] 
}) 
export class C15Component implements OnInit { 
 
 technologies = [ 
   { id: 1, nom: 'JavaScript', frameworks: ['Angular', 'React', 
'Vue'] }, 
   { id: 2, nom: 'Python'...

Hiérarchie dans les routes

Une application de gestion implémente très souvent les opérations CRUD. Elle doit pouvoir lire, modifier, supprimer et ajouter des données. La conséquence est que le nombre de routes risque d’augmenter exponentiellement.

  • /collection : pour voir l’ensemble de la collection.

  • /collection/id : pour lire l’élément avec l’identifiant id.

  • /collection/ajout/id : pour ajouter l’élément avec l’identifiant id dans la collection.

  • /collection/supp/id : pour supprimer l’élément avec l’identifiant id.

  • /collection/maj/id : pour mettre à jour l’élément avec l’identifiant id.

Afin d’améliorer l’interface et l’expérience utilisateur, Angular permet de hiérarchiser les composants et les routes. L’application va afficher une liste d’éléments de la collection et quatre boutons correspondant aux quatre actions possibles sur l’élément. Au clic, le composant responsable de l’action s’insérera à l’intérieur du composant parent.

Plus simplement, l’ajout, la suppression et la modification d’un élément de la collection ne pourra se faire qu’à l’intérieur du composant responsable du rendu de l’URL /collection.

1. Création de quatre composants

ng generate component composants/c15C 
ng generate component composants/c15R 
ng generate component composants/c15U 
ng generate component composants/c15D 

Chacun de ces composants sera responsable d’une action CRUD.

Pour l’exemple, ils ne feront qu’afficher l’action qu’ils...

Permissions

Bien entendu, certaines routes sont plus sensibles que d’autres. Que n’importe quel utilisateur puisse consulter les objets d’une collection, pourquoi pas, mais il pourrait être catastrophique que n’importe qui puisse en supprimer ou pire les modifier.

Angular propose plusieurs interfaces situées dans le paquet router afin de limiter l’accès à certaines routes et donc à certains composants.

  • CanActivate : désactive la route en fonction d’une condition.

  • CanActivateChild : désactive les routes enfants selon une condition.

  • CanDeactivate ...

Mise en pratique

1. Énoncé

À partir de l’application PokemonManager développée dans les chapitres précédents, mettez en place une barre de navigation sur la page d’accueil. À l’intérieur de celle-ci, placez cinq liens hypertextes pour :

  • revenir en page d’accueil

  • afficher le composant generations

  • afficher le composant pokemons

  • créer un compte utilisateur

  • se connecter

Créez les composants supplémentaires que vous jugerez nécessaires et utilisez les directives routerLink et <router-outlet> dans le fichier app.component.html.

images/15RI07.png

Mise en place d’une barre de navigation

Dans la suite de cet ouvrage, Firebase de Google sera utilisé pour mettre en place une véritable authentification et proposer la création de compte avec les boutons Créer un compte et Se connecter.

2. Correction

Avec Angular, tout est composant. Une barre de navigation n’est pas une exception à la règle.

ng generate component composants/barreDeNavigation 

Ce composant est assez simple puisqu’il ne comporte aucun logique métier. Encore une fois, Bulma facilite l’expérience utilisateur.

Les liens sont des directives routerLink.

<!-- C:\JavaScriptEtAngular\Angular\PokemonManager\src\app\ 
composants\barre-de-navigation\barre-de-navigation. 
component.html --> 
<nav class="navbar" role="navigation"...