Vous êtes sur la page 1sur 15

Institut Supérieur des Etudes Technologiques de Sousse

Département de Technologies de l’Informatique


Matière : Atelier FrameWork Côté Client Classe : DSI2.1
Enseignante : Raja Abdelmoumen A. U. : 2021/2022 – Semestre 1

Atelier 3 : Modules et Routage avec Angular 12

Objectifs de l’atelier

Dans cet atelier nous allons créer une application qui permet de gérer un
ensemble de films. Cette application contient deux parties :
 Une partie visible par tous les visiteurs de l’application : elle a une page
« accueil » et une page « A propos ». Cette partie est accessible par le lien :
localhost :4200
 Une partie visible par l’administrateur du site : elle permet d’ajouter un film et
d’afficher la liste des films. Cette partie est accessible par le lien :
localhost :4200/admin
On s’intéresse dans cet atelier à créer les modules de cette application, les
composants de pages et assurer le routage (navigation).

Notion de module dans Angular

Angular permet de mettre en place des applications web modulaires dans l’objectif
de mieux structurer le code, de faciliter la maintenance, la réutilisation et le partage.
Un module Angular ou NgModule est un conteneur pour un bloc cohérant de code
dédié à un domaine d'application, un flux de travail ou un ensemble de fonctionnalités
étroitement liées. Un module Angular peut contenir des composants, des services,
directives, pipes, etc. Le NgModule définit la portée des éléments qu’il contient. Les
NgModules peuvent importer des fonctionnalités exportées depuis d'autres
NgModules et exporter quelques fonctionnalités pour que d'autres NgModules
puissent les utiliser.
Chaque application Angular comprend au moins un module qui est le module
racine, qui est conventionnellement nommé AppModule et réside dans un fichier
nommé app.module.ts. Le rôle de AppModule est de lancer l’application, il est aussi
appelé pour cela le module bootstrap.
Bien qu'une petite application puisse avoir un seul NgModule, la plupart des
applications ont besoin de plusieurs modules de fonctionnalités. Les modules d’une
application sont généralement imbriqués de façon à former une arborescence dont le
root module AppModule est la racine.
L’application fait aussi appel à des modules externes provenant de bibliothèques
comme le module RouterModule pour la gestion des routes, le HttpClientModule pour
1
la gestion des requêtes réseaux, ou encore le FormsModule pour la gestion des
formulaires.

La documentation officielle de Angular donne des suggestions sur les types de


modules qu’on peut créer. Les types de modules proposés sont :

• Module de domaine ou de fonctionnalités : est organisé autour d’une


fonctionnalité.
• Module Routé : le composant supérieur du module agit comme la destination
d’un itinéraire de navigation.
• Module de Routage : fournit la configuration de routage pour un autre module.
• Module de services : fournit les services tels que l’accès aux données.
• Module partagé (Shared) : ce module met un ensemble de composants, de
directives et de pipes à la disposition des autres modules.

Un NgModule est défini par une classe décorée avec @NgModule (). Le décorateur
@NgModule () est une métadonnée, dont les propriétés décrivent le module. Les
propriétés les plus importantes sont les suivantes :

• declarations : Les composants, directives et pipes appartenant à ce NgModule.


• exports : Le sous-ensemble de déclarations qui devrait être visible et utilisable
dans les modèles de composants des autres NgModules.
• imports : Les classes exportées depuis d'autres modules, dont on a besoin dans
ce module.
• providers : Fournisseurs de services invoqués dans ce NgModule. Ces services
deviennent accessibles dans toutes les parties de l'application.
• bootstrap : Cette propriété ne concerne que le module racine. Il faut y
renseigner le composant racine, c'est-à-dire le composant qui sera affiché au
lancement de l’application.
Voici une définition simple du NgModule racine.

src/app/app.module.ts

import { NgModule } from '@angular/core';


import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [ AppComponent ],
imports: [BrowserModule, AppRoutingModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

2
Notions de « Lazy-loading feature modules » et « Preloading modules »

Par défaut, les NgModules sont chargés avec impatience, ce qui signifie que dès
que l'application se charge, tous les NgModules le font aussi, qu'ils soient ou non
immédiatement nécessaires. Pour les applications volumineuses avec de nombreux
routes, il recommandé de choisir le chargement paresseux (Lazy-loading) : un modèle
de conception qui charge les NgModules selon les besoins. Le chargement paresseux
permet de réduire la taille initiale des lots, ce qui à son tour contribue à réduire les
temps de chargement.
Le préchargement des modules (Preloading modules) améliore l'expérience de
l’utilisateur en chargeant des parties de l’application en arrière-plan afin que les
utilisateurs n'aient pas à attendre le téléchargement des éléments lorsqu'ils activent
une route.

Notions de Routage dans Angular

Les applications Web Monopage (Single Web Application) sont accessibles via une
page web unique et évite le chargement de nouvelle page lors de la navigation. Le
contenu est affiché dynamiquement en fonction de actions de l’utilisateur et permet
ainsi une fluidifier de l’expérience de l’utilisateur.
Une SPA requiert un système de routage (routing) qui permet aux utilisateurs de
garder leurs habitudes de navigation :
• Utiliser l'historique de leur navigateur (e.g. boutons back et next),
• Copier les liens,
• Ajouter une vue à leurs favoris,
• Ouvrir une vue dans une nouvelle fenêtre via le menu contextuel

Pour gérer la navigation entre les vues, Angular utilise un Routeur. Pour assurer la
navigation, le routeur interprète une adresse URL comme étant un ordre de
changement de vue. Pour inclure un lien, le développeur doit faire appel au routeur
(routerLink) à la place de <a href="adresse">.

routerLink : Lorsqu'il est appliqué à un élément dans un modèle, fait de cet élément
un lien qui initie la navigation vers une route. La navigation ouvre un ou plusieurs
composants routés dans un ou plusieurs emplacements <router-outlet> sur la page.

Module de routage : Il est vivement recommandé d’utiliser un module de routage au


lieu de définir les routes dans les modules de fonctionnalités. Dans ce module, le
développeur peut définir des routes dans ce module :

{path : 'chemin', component : CompComponent},

3
Nommage des composants et modules dans Angular

Une bonne pratique est de donner des noms en minuscule aux éléments (modules,
composants, …) créés par ng generate. Si le nom est composé par deux mots, séparez-
les par un tiret (par exemple liste-films). La commande ng fera le nécessaire
(transformation en majuscule des initiales, ajout de suffixe) pour donner des noms
adéquats au éléments créés selon ses conventions de nommage. Par exemple, si vous
créez un module que vous appelez test, le nom du module créé dans le code sera
TestModule, vous pouvez ensuite très bien donner le même nom test à un composant
et ng le nommera TestComponent (mais vous allez continuez à les appeler test si vous
leur faites ultérieurement appel dans une commande ng).

Exemple 1 : routage avec les chemins

Créer un nouveau projet exempleRoutage pour tester les exemples de routage.


Définition des routes
On se donne une application qui contient un seul module qui le module racine et deux
composants comp1 et comp2.
Le module de routage est :

app-routing.module.ts

import { NgModule } from '@angular/core';


import { RouterModule, Routes } from '@angular/router';
import { Comp1Component } from './comp1/comp1.component';
import { Comp2Component } from './comp2/comp2.component';

const routes: Routes = [


{path : 'chemin1', component : Comp1Component},
{path : 'chemin2', component : Comp2Component}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Chargement du composant
La balise <router-outlet> permet de mettre à jour la vue de l’application en chargeant
le composant associé à la route sélectionnée :

app.component.html

<h2> Ceci est le contenu de appComponent</h2>


<router-outlet></router-outlet>

4
Page principale :

Chemin 1 pour comp1

Chemin 2 pour comp2

Exemple 2 : Chemins incorrects

Quand l’utilisateur tape une url qui ne correspond à aucun chemin, la page affichée est
la page principale.
On se propose de créer un composant erreur qui affiche 404 Page not found et de
rediriger tous les pages incorrectes vers ce composant.
On modifie le module le routage par :

app-routing.module.ts (extrait)

import { NgModule } from '@angular/core';


import { RouterModule, Routes } from '@angular/router';
import { Comp1Component } from './comp1/comp1.component';

5
import { Comp2Component } from './comp2/comp2.component';
import { ErreurComponent } from './erreur/erreur.component';

const routes: Routes = [


{path : 'chemin1', component : Comp1Component},
{path : 'chemin2', component : Comp2Component},
{path : '**', component : ErreurComponent}
];
** représente la route joker (tout chemin correspond à cette route).
Avec cette définition de route, la page d’accueil va correspondre à la vue du composant
Erreur.
Pour résoudre cela, on utilise la redirection :

app-routing.module.ts (extrait)

import { NgModule } from '@angular/core';


import { RouterModule, Routes } from '@angular/router';
import { Comp1Component } from './comp1/comp1.component';
import { Comp2Component } from './comp2/comp2.component';
import { ErreurComponent } from './erreur/erreur.component';

const routes: Routes = [


{path : 'chemin1', component : Comp1Component},
{path :'chemin2', component : Comp2Component},
{path :'', redirectTo : 'chemin1', pathMatch:'full'},
{path : '**', component : ErreurComponent}
];
L’option pathMatch est mise à ‘full’ pour une redirection de la page d’accueil ('')
La route joker (**) doit être placée en dernier lieu : toute route placée après la route
joker n’est pas accessible.

Exemple3 : Routage avec les liens

La page principale de l’application est la suivante :

6
Quand l’utilisateur clique sur Lien vers comp1, on a :

Quand l’utilisateur clique sur Lien vers comp2, on a :

Pour réaliser ce routage, on modifie le fichier « template » du module racine par :

app.component.html

<h2> Ceci est le contenu de appComponent</h2>


<nav>
<ul>
<li><a routerLink="chemin1">Lien vers comp1</a></li>
<li><a routerLink="chemin2">Lien vers comp2</a></li>
</ul>
</nav>
<router-outlet></router-outlet>

Routage modulaire
Lorsque l’application contient d’autres modules que le AppModule, il est recommandé
de mettre les routes des modules de fonctionnalités dans des modules de routage
associés à ces modules de fonctionnalités. Ces modules de routage, vont faire le
routage avec RouterModule.forChild(routes) au lieu de
RouterModule.forRoot(routes) qui est utilisé par le module de routage du module
Racine.
Exemple de module de routage pour un module de fonctionnalité nommé : module1

7
module1-routing.module.ts (extrait)

import { NgModule } from '@angular/core';


import { Routes, RouterModule } from '@angular/router';
const routes: Routes = []; //Tableau à remplir par des routes
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class Module1RoutingModule { }

Partie pratique 1 : Création de deux modules avec le « lazy-loading » et choix


de statégie de « Preloading modules»

Pour réaliser notre application de gestion de films, nous allons créer deux modules de
fonctionnalités :
• Un module qu’on appellerai « visiteur » qui gère la partie visiteur
• Un module qu’on appelai module « admin » qui gère la partie
administration

AppModule

visiteur admin

1. Créer un nouveau projet appelé films.


ng new films --routing -–style css
L’option --routing permet de créer un module de routage et l’option --style
permet de choisir le style des composants.
Si on ne met pas ces deux options, Angular-CLI nous posera les deux questions
de routage et de style au début de la création du projet.

Il y a deux étapes principales pour configurer un module de fonctionnalité à


chargement paresseux :
 Créer le module de fonctionnalité avec la CLI, en utilisant l'indicateur --route.
 Configurez les itinéraires.

8
2. Créer le premier module visiteur à chargement paresseux. Avec la console, se
placer au répertoire du projet films et taper :
ng generate module visiteur --route visiteur --module app.module

L’option --route permet de créer un module « lazy loading » vers la route visiteur
représenté par un composant visiteur qui sera automatiquement crée.
L’option –module précise le module parent.
Cette commande crée un dossier visiteur qui contiendra le module de fonctionnalité
visiteur. Avec la commande ng, les chemins qu’on indique sont calculés à partir du
répertoire src/app : ici le répertoire visiteur est placé sous src/app.
Dans le répertoire visiteur, on trouve :
• Le fichier visiteur.module.ts qui contient la classe VisiteurModule
représentant le NgModule.
• Le fichier visiteur-routing.module.ts qui est le module du routage du
module visiteur.
• Les fichiers d’un composant VisteurComponent (.ts, .html, .css) qui est
créé automatiquement.
Étant donné que le nouveau module est censé être chargé paresseux, la commande
n'ajoute pas de référence du nouveau module de fonctionnalité dans le fichier du
module racine de l'application, app.module.ts. Au lieu de cela, il ajoute la route visiteur
au tableau routes déclaré dans le module de routage fourni en tant qu'option --
module.
3. Ouvrir le fichier app-routing.module.ts et vérifier que le tableau
Route contient :
app-routing.module.ts (extrait)
{
path: 'visiteur',
loadChildren: () => import('./visiteur/visiteur.module').then(m =>
m.VisiteurModule)
}

Angular utilise loadChildren (au lieu de component) dans la configuration des routes
pour permettre le « lazy loading » des modules.
4. Pour choisir une statégie de préchargement, modifier le fichier app-
routing.module.ts comme suit :

9
app-routing.module.ts (extrait)
import { PreloadAllModules } from '@angular/router';

@NgModule({
imports: [RouterModule.forRoot(routes,{
preloadingStrategy: PreloadAllModules
} )],
Avec ce code, nous avons défini une stratégie de préchargement qui consiste à cha
5. Modifier le contenu de app.component.html par :
app.component.html
<router-outlet></router-outlet>

6. Vérifier le lien visiteur :

7. Générer le module admin, de la même façon que le module visiteur et vérifier


le lien admin

8. Vérifier que l’affichage de la route par défaut (l’url localhost :4200) donne une
page vide.

9. Modifier la route par défaut vers le module visiteur.

10
Partie pratique 2 : Création de composants de pages pour chaque module et
routage imbriqué

10. Pour le module visiteur, nous allons créer deux composants home-visiteur et
apropos qui sont des composants de pages du module visiteur. Taper la
commande suivante :
ng generate component visiteur/home-visiteur --module visiteur
ng generate component visiteur/apropos --module visiteur

Nous voulons aboutir au résultat suivant pour la page d’accueil :


localhost :4200/visiteur : redirection vers la page home-visiteur.

Ici, le composant visiteur affichera un menu vers les composants home-visiteur et


apropos et aussi affichera le composant sélectionné par le lien. Donc, le composant
visiteur devrait avoir comme template :

11
visiteur.component.html

<h1>
Bienvenue Visiteur
</h1>
<nav>
<a routerLink="home-visiteur">Accueil</a>&nbsp;
<a routerLink="apropos">A propos</a>
</nav>
<router-outlet></router-outlet>

Le composant visiteur aura alors dans son template la balise <router-outlet>. Cela
signifie que vous ajoutez un deuxième <router-outlet> à votre application, car il
s'ajoute au <router-outlet> du app.component.html : il s’agit alors du routage
imbriqué.
Routage imbriqué (Nesting routes)
Au fur et à mesure que votre application devient plus complexe, vous souhaiterez peut-
être créer des routes relatives à un composant autre que votre composant racine. Ces
types de routes imbriquées sont appelées routes enfants. Cela signifie que vous ajoutez
un deuxième <router-outlet> à votre application, car il s'ajoute au <router-outlet> dans
AppComponent.
Dans cet exemple, il existe deux composants enfants, enfant-a et enfant-b. Ici,
PereComponent a son propre <nav> et un second <router-outlet> en plus de celui
d'AppComponent.

pere.component.html
<h2>Pere Component</h2>

<nav>
<ul>
<li><a routerLink="enfant-a">Enfant A</a></li>
<li><a routerLink="enfant-b">Enfant B</a></li>
</ul>
</nav>

<router-outlet></router-outlet>

Dans le module de routage :


app.routing.module.ts
const routes: Routes = [
{
path: 'pere-component',
component: PereComponent,
children: [
{
path: 'enfant-a',
component: EnfantAComponent,

12
},
{
path: 'enfant-b',
component: EnfantBComponent,
},
],
},
]

11. Modifier les fichiers visiteur.component.html, visiteur-routing.module.ts


visiteur.component.css comme suit :
visiteur.component.html
<h1>
Bienvenue Visiteur
</h1>
<nav>
<a routerLink="home-visiteur" >Accueil</a>&nbsp;
<a routerLink="apropos" >A propos</a>
</nav>
<router-outlet></router-outlet>

Visiteur-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AproposComponent } from './apropos/apropos.component';
import { HomeVisiteurComponent } from './home-visiteur/home-
visiteur.component';
import { VisiteurComponent } from './visiteur.component';
const routes: Routes = [

{
path: '', component: VisiteurComponent,
children: [
{path: 'apropos', component: AproposComponent },
{path: 'home-visiteur', component: HomeVisiteurComponent },
] ,
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class VisiteurRoutingModule { }

13
visiteur.component.css
nav a
{
text-decoration: none;
display:inline-block;
margin : 0px;
padding:5px;
}
nav
{
background-color: #f8f8f8;
}
a:active
{
color:black;
}

Vérifier le résultat sur le navigateur.


12. Modifier la route par défaut, de telle façon que le composant home-visiteur est
affiché par défaut.
La directive routerLinkActive
Cette directive permet de créer une distinction visuelle pour les éléments associés à
une route activr. Par exemple, le code suivant met en évidence le lien « Accueil »
lorsque le routeur active la route associée :
<a routerLink="accueil" routerLinkActive="active">Accueil</a>
Dans le fichier css corresponant au lien, on trouve la classe active
.active {backgroud-color : red}
Ainsi, si la route active est Accueil, sa couleur de fond devient rouge.
13. Utiliser la directive routerLinkActive pour changer le rendu visuel de la route
active. Le code css est : background-color: #dfdfdf;
14. Pour le module admin, créer deux composants lister-films et ajouter-film qui
sont des composants de pages du module admin.
15. Suivre les mêmes étapes que le module visiteur pour avoir le résultat suivant du
module admin

14
16. Ajouter un module erreur avec un composant erreur pour lui rediriger toutes
les urls incorrectes

15

Vous aimerez peut-être aussi