Objectif général : Prendre en main l’un des Frameworks JavaScript les plus utilisés pour développer efficacement des applications Web
Objectifs spécifiques
Structurer l’application avec les composants
Gérer les données dynamiques avec le Data binding
Enrichir le HTML avec des directives prédéfinies
Interagir avec un utilisateur par le biais des formulaires
Organiser et partager le code métier avec les services
Communiquer avec un serveur via le service HttpClient
Afficher des vues en fonction de l’URL avec le routage
2. Objectif général
Prendre en main l’un des Frameworks JavaScript les
plus utilisés pour développer efficacement des
applications Web
2
3. Objectifs spécifiques
• Structurer l’application avec les composants
• Gérer les données dynamiques avec le Data binding
• Enrichir le HTML avec des directives prédéfinies
• Interagir avec un utilisateur par le biais des formulaires
• Organiser et partager le code métier avec les services
• Communiquer avec un serveur via le service HttpClient
• Afficher des vues en fonction de l’URL avec le routage
3
4. Sommaire
1) Présentation d’Angular
2) Mise en place de l’environnement de développement
3) Composants
4) Données d’un composant parent vers son composant
fils
5) Directives
6) Infos d’un composant fils vers son composant parent
7) Formulaires
8) Services
9) Communiquer avec un serveur
10) Routage
4
5. Présentation d’Angular
• Problématiques : comment
faciliter le développement, côté client, d’une Web app ?
adapter le HTML au développement d’une Web app ?
• Solution : Framework JavaScript qui étend le HTML
• Angular : framework JavaScript open source, créé en
octobre 2010 par des développeurs de Google
• Quelques principes d’Angular
SPA (Single Page Application) : application monopage
Data binding : quand le modèle change, la vue peut
refléter automatiquement le changement et vice-versa.
Injection de dépendances : création dynamique des
dépendances entre classes
Usage : Web, mobile, desktop 5
6. Mise en place de l’environnement
de développement
1) Installer les prérequis node.js et NPM
Télécharger et installer la dernière version LTS de Node.js à
partir de https://nodejs.org/en/download/
2) Installer globalement Angular/CLI
npm install -g @angular/cli
3) A partir d’un répertoire choisi, créer un nouveau projet
Angular
ng new school-app
4) Naviguer dans le dossier du projet
cd school-app
5) Lancer le serveur de développement
ng serve --open
6) Avec un navigateur, requêter
http://localhost:4200 6
7. Composants
illustration
7
Liste des étudiants de JS Dev
Fatou Dia
Saliou Diouf
Alain Gomis
X
X
X
Prénom de l’étudiant
Ajouter
Composant app
Composant dlassroom
Angular School App
Composant addStudent
Composant student
Nom de l’étudiant
8. Composants
présentation
• Application = arborescence de composants dont la racine
est AppComponent
• Composant : partie de l’application
• Composant = classe + template + sélecteur + style
• Classe = logique = données + comportement
• Template = rendu = HTML + syntaxes Angular
• Sélecteur = élément d’instanciation
• Style = CSS
8
12. Composants
création avec le CLI d’Angular
• Syntaxe de la commande (à partir de la racine de l’app)
ng generate component nomDuComposant
• Résultat
Création d’un sous-répertoire contenant les fichiers
nécessaires au composant
Déclaration du composant dans le module racine
Ce composant peut être instancié dans n’importe quel
autre composant grâce au sélecteur app-nomDuComposant
• Exemple
Avec une nouvelle fenêtre, se placer sur school-app et lancer
ng generate component classroom
12
13. Composants
création avec le CLI d’Angular - Exemple
• Générer le composant student
• A la classe de student.component.ts
déclarez la propriété student de type any
Dans ngOnInit(), initialiser student avec le littéral
{prenom:'Fatou', nom:'Dia'}
• Remplacer le contenu de student.component.html par ce
paragraphe contenant des interpolations
<p> {{student.prenom}} {{student.nom}} </p>
• Instancier le composant student dans le composant
classroom en remplaçant tout le contenu de
classroom.component.html par
<app-student></app-student>
• Instancier le composant classroom dans le composant app
• Rendu (http://localhost:4200) :
Fatou Dia
13
14. Données d’un composant parent vers
son composant fils
procédure
14
• Dans le composant parent, définir la propriété contenant la
donnée à transférer au composant fils
Exemple dans Classroom :
students = [{prenom:'Fatou', nom:'Dia'}, …] ;
• Dans le composant fils
déclarer la propriété qui recevra la donnée transférée en la
faisant précéder du décorateur @Input()
Exemple dans Student :
@Input() student;
Importer Input à partir de @angular/core
• Dans le template du parent, utiliser le « property binding » pour
relier la donnée du parent à la propriété du fils
Exemple dans le template de classroom :
<app-student [student]="students[0]" ></app-student>
…
15. Données d’un composant parent vers
son composant fils
exemple
15
• Dans le composant Student, faire précéder la propriété student du
décorateur @Input() et commenter son initialisation ds ngOnInit()
• Ds la classe du composant Classroom, définir la propriété
nom = 'JS Dev' et la propriété students
• Remplacer le contenu du template de Classroom par
16. Directives
présentation
• Directive = instructions intégrées dans le DOM
• Objectif : étendre les capacités du langage HTML
• Directives structurelles
Objectif : modifier le DOM
Exemples : NgFor, NgIf
Elle sont généralement utilisées avec un astérisque
• Directives attribut
Objectif : modifier l’apparence ou le comportement d’un
élément du DOM
Exemples : NgModel, NgStyle, NgClass
16
17. Directives
NgFor
• NgFor permet de boucler sur une collection et d'injecter les
éléments dans le DOM
• Syntaxe
<element *ngFor="let <value> of <collection>" >.
17
• Exemple : répéter l’instanciation du composant Student
Dans le template du composant Classroom, remplacer les trois
composants Student par :
18. Directives
NgIf
• Exemple : Mettre à jour le contenu du template de Classroom par
18
• NgIf permet de supprimer ou de recréer un élément dans le DOM
suivant la valeur booléenne d’une expression
• Syntaxe
<div *ngIf="condition else contenu_alternatif">
Contenu à afficher uniquement si la condition est vraie
</div>
<ng-template #contenu_alternatif>
Contenu à afficher uniquement si la condition est fausse
</ng-template>
19. Infos d’un composant fils vers son
composant parent
présentation
• Problème
Comment un évènement natif (clic, soumission, …) sur le fils peut
être géré par le parent ?
Exemple : un clic sur Student déclenche une suppression d’un
étudiant sur la liste gérée par le parent
• Solution
1) Lorsque l’évènement natif se passe, le fils émet un évènement
personnalisé pour informer le parent
2) Lorsque l’évènement personnalisé se passe, le parent fait le
traitement final attendu
19
20. Infos d’un composant fils vers son
composant parent
procédure
• Faire un « event binding » côté fils : lier une événement (clic,
survol, …) effectué sur le DOM à un traitement dans le composant
Exple sur Student : <button (click)="handleDelete()">X</button>
• Le gestionnaire de l’évènement du fils doit émettre un évènement
personnalisé (avec EventEmitter) adressé au parent (avec Output)
Exemple sur Student
@Output() studentToDelete:EventEmitter<any> = new EventEmitter();
handleDelete(){ this.studentToDelete.emit(); }
• Cet évènement personnalisé peut recevoir des données en
paramètres
• Faire un « event binding » côté parent : sur le composant fils, avec
l’évènement personnalisé et son gestionnaire (à définir dans le
composant parent)
Exemple sur Classroom 20
21. Infos d’un composant fils vers son
composant parent
exemple : retirer un étudiant de la classe
• Sur le template de Student, juste après le nom de l’étudiant,
ajouter : <button (click)="handleDelete()">X</button>
• Dans la classe de Student, ajouter
@Output() studentToDelete:EventEmitter<any> = new EventEmitter();
handleDelete(){ this.studentToDelete.emit(); }
NB : Importer Output et EventEmitter à partir de @angular/core
• Sur le template de Classroom, ajouter au sélecteur <app-student>
la propriété : (studentToDelete)="deleteStudent(student)"
• Dans la classe de Classroom, ajouter
deleteStudent(student) {
this.students = this.students.filter( (elt) => (elt !== student) );
}
21
22. Formulaires
traitement
Traiter le formulaire en le référençant avec ses champs et en
gérant sa soumission
• NgForm : lie automatiquement un objet au formulaire pour sa
validation et son traitement
• NgModel : enregistre, dans Angular, un champ dont elle est un
attribut. L’attribut name doit être obligatoirement présent
• .value :
propriété de l’objet lié au formulaire
objet ayant pour propriétés les noms des champs
enregistrés
chaque nom de champ stocke la valeur du champ
• NgSubmit : détecte la soumission du formulaire
• NB : FormsModule est à importer depuis @angular/forms et doit
être ajouté dans la section imports de app.module.ts 22
23. Formulaires
exemple : ajouter un étudiant
• Générer le composant addStudent
• Dans le template de AddStudent, coder le formulaire
23
NB : #myForm="ngForm" assignation d’un objet NgForm à la
variable locale myForm associée au formulaire
• Dans la classe de AddStudent, ajouter
NB : importer NgForm à partir de @angular/forms
24. Formulaires
exemple : ajouter un étudiant (suite)
• Dans le template de Classroom, juste au dessus du h1,
instancier AddStudent comme suit
24
• Dans la classe de de Classroom, ajouter
• Dans app.module.ts,
importer FormsModule depuis @angular/forms
et l’ajouter dans la section imports
25. Formulaires
validation
• Validation : vérifier si les informations saisies sont correctes
• Quelques règles de validation : required, number, email, maxlength,
minlength, pattern
• Qlq propriétés de validation d’un formulaire ou d’un champ
valid : vraie si toutes les règles sont respectées
invalid : vraie si au moins une des règles est violée
touched : vraie si l’élément a été visité
pristine : vraie si l’élément n’a pas été modifié
dirty : vraie si l’élément a été modifié
errors.<regle> : vraie si la règle de validation est violée
• Syntaxes d’accès
nomFormulaire.propriété et nomChamp.propriété
avec
#nomFormulaire="ngForm" et #nomChamp="ngModel"
• Afficher tout message d’erreur avec la directive NgIf
25
27. Services
présentation
• Pbl : comment isoler certaines données et fonctionnalités
réutilisables ?
Exemple : communiquer avec le backend
• Sol : enveloppées ces données et fonctionnalités réutilisables
dans des classes détachées de l’interface
• Service : classe TypeScript décorée par @Injectable dont
l’objectif est d’organiser et de partager le code métier
• Exemple de service natif :
HttpClient pour exécuter des requêtes AJAX
• Commande de création : ng generate service nomService
• Il est fourni (provide), par défaut, à la « root injector » pour que
sa réutilisation dans l’application soit globale
• singleton : instancié une seule fois et cette instance est ensuite
utilisée partout 27
28. Services
exemple – création d’un modèle
• Créer la classe « Apprenant » servant de modèle
ng generate class apprenant
• Mettre à jour « apprenant.ts »
export class Apprenant {
constructor(private prenom: string, private nom: string){}
get getPrenom() : string { return this.prenom; }
set setPrenom(prenom : string) { this.prenom = prenom; }
get getNom() : string { return this.nom; }
set setNom(nom : string) { this.nom = nom;}
}
28
29. Services
exemple – création d’un service
• Exécuter la commande : ng generate service apprenant
• Rajouter à la classe de « apprenant.service.ts »
29
• NB : importer la classe « Apprenant » dans « apprenant.service.ts »
import { Apprenant } from "./apprenant";
30. Services
exemple – utilisation d’un service
Dans « classroom.component.ts »
• students devient
students: Array<Apprenant> = [];
• Injecter le service dans le composant
constructor(private apprenantService:ApprenantService) {}
• Modifier la méthode ngOnInit()
ngOnInit() {
this.students = this.apprenantService.getAll();
}
• importer les classes « Apprenant » et « ApprenantService »
import { Apprenant } from "../apprenant";
import { ApprenantService } from '../apprenant.service’;
30
31. Communiquer avec un serveur
présentation de HttpClient
• HttpClient : service qui facilite la communication avec un
serveur HTTP distant via l'objet XMLHttpRequest
• HttpClient dispose des méthodes get(), post(), put(), patch()
delete() pour effectuer des requêtes HTTP
• Chacune des méthodes construit un « Observable » qui attend
un abonnement ( .subscribe() ) pour exécuter la requête
• get() permet de retourner le type de l'objet attendu avec la
syntaxe suivante : .get<typeAttendu>()
• Prérequis d’utilisation de HttpClient
Importer HttpClientModule dans AppModule
Injecter HttpClient dans un service de l’application
HttpClientModule et HttpClient sont dans
@angular/common/http
31
32. Communiquer avec un serveur
exemple : installation et démarrage d’un serveur factice JSON
• Json-server : serveur JSON de test pour recevoir des requêtes
HTTP envoyée par Angular et retourner des réponses
• Documentation : https://github.com/typicode/json-server
• Installer Json-server : npm install -g json-server
• Créer, à la racine de l’application, le fichier apprenants.json
servant de base de données
• Se placer dans le répertoire contenant apprenants.json et
démarrer le serveur avec la commande
json-server --watch apprenants.json
• Notation de l’URL servant de ressource aux requêtes HTTP
"http://localhost:3000/apprenants"
32
34. Communiquer avec un serveur
exemple : utilisation de HttpClient par apprenant.service.ts
34
Importer
HttpClient
Ressource
des requêtes
Injecter
HttpClient
Requête pour
récupérer
tous les
apprenants
Requête pour
ajouter un
apprenant
35. Communiquer avec un serveur
exemple : exploitation de la requête GET ds le composant Classroom
• Dans ngOnInit() de classroom.component.ts, remplacez
this.students = this.apprenantService.getAll();
par
this.apprenantService.getAll()
.subscribe( data => this.students = data );
• Dans app.module.ts, importer HttpClientModule à partir de
@angular/common/http et ajouter HttpClientModule dans la
section imports
35
36. Communiquer avec un serveur
exemple : exploitation de la requête POST ds classroom.component.ts
• Remplacer le contenu de la méthode addStudent par
36
• Ajouter un apprenant avec le formulaire
37. Routage
présentation
• Principe du SPA
charger une seule page (index.html)
y présenter, au besoin, tout composant de l’application
• Problème
Comment naviguer entre les différents composants, en
changeant l'URL du navigateur, en modifiant l'historique du
navigateur et en gardant l'état de l'interface utilisateur
synchronisé ?
• Solution : routage
• Objectif : faire correspondre un chemin (path) donnée de l’URL
à un composant et afficher sa vue précise
37
38. Routage
création des routes
• Création des routes dans app.module.ts
route = objet avec les propriétés path et component ou
redirectTo
Définir les routes dans un tableau de type Routes
Enregistrer les routes dans l’application en passant leur
tableau à forRoot() de RouterModule
NB 1 : Routes et RouterModule sont à importer depuis
@angular/router
NB2 : RouterModule doit être ajouté dans la section imports
• Emplacement d’affichage des composants dans le template
ajouter <router-outlet></router-outlet>
38
39. Routage
exemple sur la création de routes
• Ajouter dans app.module.ts
import { RouterModule, Routes } from "@angular/router";
Juste avant @NgModule
const appRoutes: Routes = [
{path:'classroom', component: ClassroomComponent},
{path:'student/:id', component: StudentComponent}
];
• Dans imports, ajouter
RouterModule.forRoot(appRoutes, {enableTracing:true})
• Ajouter dans app.component.html
<router-outlet></router-outlet>
• Tester le chemin 'classroom' 39
40. Routage
navigation
• Depuis un template
Remplacer href par routerLink pour référencer un path
Exemple : ds le template de App, juste avant <router-outlet>,
ajouter
<nav>
<a routerLink="/classroom">Classroom</a>
<a routerLink="/student/1">Apprenant 1</a>
<a routerLink="/student/2">Apprenant 2</a>
</nav>
• Depuis une classe
navigateByUrl(string) ou navigate(array) de Router
Router : service à injecter et à importer depuis
@angular/router
Exemple : this.router.navigateByUrl("/classroom")
Exemple : this.router.navigate(["/", "classroom"]) 40
41. Routage
paramètres de routes
• Paramètre de route : portion variable d’une route
• Syntaxe de création du paramètre : chemin/:nomParam
• Deux syntaxes de récupération des valeurs
this.nomParam =
this.route.snapshot.paramMap.get('nomParam');
this.route.paramMap.subscribe(params => {
this.nomParam = params.get('nomParam');
});
• La 1ère syntaxe ne met pas à jour le composant en cas de
changement du paramètre
• snapshot et paramMap : propriétés du service
ActivatedRoute à injecter et à importer depuis
@angular/router
41
42. Routage
exemple sur les paramètres de routes
• Ajouter à apprenants.service.ts la méthode
42
• Remplacer le contenu de student.component.html par
43. Routage
suite de l’exemple sur les paramètres de routes
• Dans student.component.ts, modifier le constructeur et
ngOnInit()
43
• NB : importer ApprenantService et ActivatedRoute
• Relancer éventuellement la commande :
json-server --watch apprenants.json
• Tester le path 'student/:id'
LTS (en français Support à long terme) désigne une version spécifique d'un logiciel dont le support est assuré pour une période de temps plus longue que la normale.
https://medium.com/macoclock/update-your-node-js-on-your-mac-in-2020-948948c1ffb2
https://www.journaldunet.fr/web-tech/developpement/1441019-comment-mettre-a-jour-angular-cli-dans-sa-derniere-version/
ng new mon-premier-projet
This setting helps improve maintainability and catch bugs ahead of time.
For more information, see https://angular.io/strict No
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? CSS
Steps : install npm package offline
Install all the package(s) on a remote machine which has an internet access. In my case I'm using on both remote as well as local machines and my requirement was of installation of on local machine . So I run below command on my remote machine to install Windows express.js express.js C:\Users>npm install -g express-generator`
After installation of express.js I created an app on my remote machine using: C:\Users\Name\Desktop>express Project` C:\Users\Name\Desktop\Project>npm install -g =>to install all other dependencies globally*
Now browse to location where npm 's global modules are stored, you can view the location by C:\Users>npm config get prefix Generally in Windows its C:\Users\{Username}\AppData\Roaming\
Simply copy the npm and npm-cache folder of your remote machine.
And place both copied folders viz. and into your local machine on same location thats npm npm-cache C:\Users\{Username}\AppData\Roaming
Sélecteur = Un sélecteur demande à Angular d'instancier ce composant partout où il trouve la balise correspondante dans le modèle HTML.
{{student.prenom}} est une interpolation : mécanisme permettant de modifier le DOM à partir du modèle
Next step : afficher une liste de trois étudiants. La liste sera construite dans Classroom
Next step : et s’il y avait 100 étudiants, comment afficher la liste ?
Next step : et s’il y a aucun étudiant, comment gérer l’affichage ?
Next step : et si l’on souhaite retirer un étudiant de la classe ?
Il est impossible d’appliquer plusieurs directives sur un même élément du DOM
ng-container évite d’ajouter une div qui recevra une directive
ng-template delimite une partie du template pour pa exemple l’identifiant avec une référence de template
Next step : et si l’on souhaite ajouter un étudiant dans la classe ?
Next step : et si la liste des étudiants doit être utilisée par d’autres composants ?
The object f.firstName.errors can be null. Use the safe navigation operator ?:
*ngIf="f.firstName.errors?.required"
Next step : et si la liste des étudiants se trouve côté backend ?
Observables : Emit multiple values over a period of time - Are lazy: they’re not executed until we subscribe to them using the subscribe() method - Have subscriptions that are cancellable using the unsubscribe() method which stops the listener from receiving further values - Provide the map for forEach, filter, reduce, retry, and retryWhen operators. - Deliver errors to the subscribers.
Promises Emit a single value at a time.-.Are not lazy: execute immediately after creation. -.Are not cancellable. - Don’t provide any operations. Push errors to the child promises
Steps : install npm package offline
Install all the package(s) machine which has an internet access. C:\Users>npm install -g express-generator`
After installation of express.js I created an app on my remote machine using: C:\Users\Name\Desktop>express Project` C:\Users\Name\Desktop\Project>npm install -g =>to install all other dependencies globally*
Now browse to location where npm 's global modules are stored, you can view the location by C:\Users>npm config get prefix Generally in Windows its C:\Users\{Username}\AppData\Roaming\
Simply copy the npm and npm-cache folder of your remote machine.
And place both copied folders viz. and into your local machine on same location thats npm npm-cache C:\Users\{Username}\AppData\Roaming
href : recharge toute la page
RouterLink : charge juste le composant