Académique Documents
Professionnel Documents
Culture Documents
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).
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.
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 :
src/app/app.module.ts
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.
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.
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).
app-routing.module.ts
app.component.html
4
Page principale :
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)
5
import { Comp2Component } from './comp2/comp2.component';
import { ErreurComponent } from './erreur/erreur.component';
app-routing.module.ts (extrait)
6
Quand l’utilisateur clique sur Lien vers comp1, on a :
app.component.html
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)
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
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>
8. Vérifier que l’affichage de la route par défaut (l’url localhost :4200) donne une
page vide.
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
11
visiteur.component.html
<h1>
Bienvenue Visiteur
</h1>
<nav>
<a routerLink="home-visiteur">Accueil</a>
<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>
12
},
{
path: 'enfant-b',
component: EnfantBComponent,
},
],
},
]
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;
}
14
16. Ajouter un module erreur avec un composant erreur pour lui rediriger toutes
les urls incorrectes
15