SlideShare une entreprise Scribd logo
1  sur  90
Télécharger pour lire hors ligne
Angular Avancé
INSTITUT SUPÉRIEUR DES ÉTUDES TECHNOLOGIQUES DE SIDI BOUZID
ENSEIGNANT: NIZAR MAATOUG
GROUPE: MDW2 2019-2020
Résultats
➢ Développer une application Angular en suivant les bonnes pratiques
➢ Consolider et pratiquer les concepts de base
➢ Optimiser les performances d’une application Angular
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
2
Application de Gestion de voitures
 On souhaite développer une application de gestion de voitures.
 Chaque voiture est caractérisée par:
 un identifiant
 Une marque
 Un modèle
 une couleur
 L’application permet de:
 Consulter les voitures
 Ajouter une nouvelle voiture
 Mettre à jour une voiture
 Supprimer une voiture
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
3
Démo & code source
 Démo: https://www.youtube.com/watch?v=ddU92H6fazk
 Code source : https://github.com/nizar-maatoug/gestion-voitures
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
4
Environnement de développement
 Bibliothèques javascript Node JS
 Angular CLI
 Environnement de développement intégré VS code
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
5
Création du projet
 ng new gestion-voitures --routing
 Installation de bootstrap:
 npm install -- save bootstrap
 npm install --save jquery
 npm install --save popper.js
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
6
Mise à jour angular.json
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
7
Architecture de
l’application
8
Voitures
AppModule
SharedModule
RoutingModule
Architecture de l’application
 Comment découper mon application en modules ?
 Combien de modules dois-je créer ?
 Où placer mes composants, comme la barre de
navigation par exemple ?
 Dans quel dossier regrouper mes services ?
 Comment modéliser mes entités avec des
classes TypeScript ?
 Ou placer les fichiers nécessaires pour
l’authentification ?
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
9
10
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
?
Architecture: Rappel
 Une application Angular est structurée en modules
 Un module regroupe logiquement des composants
graphiques, des directives, des pipes et d’autres
sous-modules.
 Un module fournit des services
 Par défaut, une application Angular contient un seul
module principal AppModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
11
12
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
AppModule
AppComponent
Nav-barComponent
FooterComponent
VoitureComponent
ListeVoitureComponent
Pour une petite application, le
module principal AppModule est
suffisant.
13
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
AppModule
AppComponent
Nav-barComponent
FooterComponent
VoitureComponent
ListeVoitureComponent
.
.
.
Mais pour les moyennes et grandes
applications, AppModule sera très
chargé, donc il est difficile de faire
évoluer l’application, de la maintenir
ou même de repérer un fichier
14
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
AppModule
AppComponent
Nav-barComponent
FooterComponent
VoitureModule
VoitureComponent
ListeVoitureComponent
.
.
.
DetailVoitureComponent
EditVoitureComponent
Il faut penser à organiser
l’application par module pour
chaque fonctionnalité: exemple:
gestion voiture
15
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
AppModule
Fonctionnalité1 Fonctionnalité2 Fonctionnalité3
SharedModule: Minimiser les importations
 Souvent, des modules, des composants et des
directives sont sollicités par plusieurs composants
dans différents modules.
 Une bonne pratique consiste à regrouper ces
dépendances dans un seul module appelé
SharedModule (ou module partagé)
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
16
17
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
Fonctionnalité1 Fonctionnalité2 Fonctionnalité3
Des importations répétitives dans plusieurs modules
18
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
Fonctionnalité1 Fonctionnalité2 Fonctionnalité3
SharedModule
exports [ ]
Exemple:
CommonModule un
module angular qui
exporte les directives de
base: NgIF, NgFor,…
Solution: Factoriser ces importations répétitives dans un
module unique: SharedModule
19
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
Fonctionnalité1 Fonctionnalité2 Fonctionnalité3
SharedModule
exports [ ]
Exemple:
CommonModule un
module angular qui
exporte les directives de
base: NgIF, NgFor,…
Solution: Factoriser ces importations répétitives dans un
module unique: SharedModule
Architecture:
Mise en place
20
Voitures
AppModule
SharedModule
RoutingModule
Démarche
 Créer le SharedModule
 Créer le module fonctionnel VoituresModules
 Importer le module SharedModule dans VoituresModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
21
Créer le module Shared
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
22
Générer le module
SharedModule
Exporter CommonModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
23
Exporter le CommonModule
pour le rendre disponible aux
modules qui importent le
SharedModule
Créer le module Voitures
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
24
Générer le module
VoituresModule
VoituresModule: importer Shared
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
25
Importer le module
SharedModule
Architecture initiale
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
26
AppModule
VoituresModule SharedModule
AppRoutingModule❑ C’est l’architecture initiale
de notre projet
❑ Elle peut évoluer au cours
du développement
❑ Mais elle est flexible,
évolutive et rend notre
projet facilement
maintenable
Exercice
 Effectuer les mises à jour
nécessaires afin d’obtenir
l’architecture suivante
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
27
AppModule
VoituresModule SharedModule
AppRoutingModule
Solution
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
28
Les services
 Un service est une classe TypeScript qui implémente
une partie de la logique métier de l’application
 Exemple: Calcul âge, ajout d’une voiture côté
serveur,...
 Permet aussi de mémoriser et partager l’état de
l’application entre plusieurs composants
 Exemple: mémoriser et partager la liste des voitures
 Il faut bien gérer l’état de l’application:
 Garantir la cohérence de l’application
 Synchroniser les composants
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
29
30
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
AppModule
Fonctionnalité1 Fonctionnalité2 Fonctionnalité3
Service
Un service fourni par le AppModule sera unique dans toute
l’application: une seule instance (Singleton)
31
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
AppModule
Fonctionnalité1 Fonctionnalité2 Fonctionnalité3
Service
Un service fourni par un module sera unique et accessible à tous les
sous-modules et les composants de ce module
32
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
Module
Composant
Sous-Composant
Service
Un service fourni par un composant sera accessible uniquement dans
le composant lui-même et ses composants fils
Bonne pratique: service
 Dans la grande majorité des cas, un service doit
avoir une seule instance dans l’application
 Dans ce cas, il doit être fourni par le AppModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
33
@Injectable({
providedIn: 'root'
})
export class VoituresService {…}
root: fourni par le module
principal AppModule
partie Backend
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
34
client Serveur
Application
Angular
Application Spring
(Java) BD
GET URL/voitures
Retourne liste voitures
GET URL/voitures/1
Retourne voiture id=1
POST URL/voitures
V
OK
V
PUT URL/voitures
V
OK
V
DELETE URL/voitures/2
OK
VoituresService (1/2)
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
35
import { HttpClient} from "@angular/common/http";
import { Observable, Subject } from 'rxjs’;
import { Voiture } from "./model/voiture.model";
import { tap } from 'rxjs/operators’;
@Injectable({
providedIn: 'root’
})
export class VoituresService {
private baseURL="http://localhost:8080/voitures";
voitureChanged=new Subject<Voiture[]>();
constructor(private http: HttpClient) { }
/**Get voitures */
getVoitures():Observable<Voiture[]>{
return this.http.get<Voiture[]>(this.baseURL);
}
/**Get voiture */
getVoiture(id:number):Observable<Voiture>{
const url= this.baseURL+ '/'+ id;
return this.http.get<Voiture>(url);
}
/**Post voiture */
postVoiture(voiture: Voiture): Observable<Voiture>{
return this.http.post<Voiture>(this.baseURL, voiture).pipe(
tap(v => this.notifyVoitureChanged())
)
}
VoituresService (2/2)
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
36
/**PUT: mettre à jour la voiture dans le serveur */
updateVoiture(voiture: Voiture): Observable<Voiture>{
return this.http.put<Voiture>(this.baseURL, voiture).pipe(
tap(v => this.notifyVoitureChanged())
);
}
/**DELETE: supprimer la voiture */
deleteVoiture(voiture: Voiture):Observable<String>{
console.log(voiture.id);
return this.http.delete<String>(this.baseURL+'/'+voiture.id).pipe(
tap(v => this.notifyVoitureChanged())
);
}
notifyVoitureChanged(){
this.getVoitures().subscribe(
voitures => this.voitureChanged.next(voitures)
)
}
Les composants:
ARCHITECTURE ET BONNES PRATIQUES
37
Angular : framework orienté composant
 Angular est un framework orienté composant
 Single Page Application (SPA): application web avec
une seule page
 L’unique page web est le socle d’une arborescence
de composants
 Problématique:
 Comment structurer ces composants d’une façon
optimale, maintenable, évolutive ?
 Comment gérer la communication entre ces
composants afin de garantir la cohérence et l’état de
l’application?
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
38
 Une application Angular
est un assemblage de
composants
 Par analogie, les
composants ressemble à
des pièces de Lego
39
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
Types des composants
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
40
Composant de
page
Composant
intelligent (smart)
Composant idiot
(dumb)
 3 types de composants:
 composant de page: conteneur
d’une arborescence de
composants, son rôle est de
structurer les composants
 Composant intelligent:
communique avec les services
 Composant idiot: moins de
logique métier, il se charge
d’afficher les données
41
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
FooterComponent : dumb
HeaderComponent : Smart
HomeComponent : page
42
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
voitureComponent: composant de page
voitureListComponent: smart
VoitureDetailComponent: smart
VoitureItemComponent : dumb
Arborescence des composants
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
43
HomeComponent
Header
VoitureComponent
VoitureList
VoitureItem
Router
VoitureDetailVoitureStart VoitureEdit
Router
PageNotFound
Footer
 Dans le module AppModule, création des composants:
 HomeComponent
 HeaderComponent
 FooterComponent
 PageNotFoundComponent
 Dans le module VoitureModule, création des composants:
 VoituresComponent
 VoitureListComponent
 VoitureItemComponent
 VoitureStartComponent
 VoitureDetailComponent
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
44
Manip: création des composants
Manip: création des composants
 ng g c home
 ng g c header
 ng g c footer
 ng g c page-not-found
 ng g c voitures --module=voitures
 ng g c voitures/voiture-list --module=voitures
 ng g c voitures/voiture-list/voiture-item –module=voitures
 ng g c voitures/voiture-start --module=voitures
 ng g c voitures/voiture-detail --module=voitures
 ng g c voitures/voiture-edit --module=voitures
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
45
AppModule
VoituresModule
Résultats
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
46
Home: composant principal
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
47
@NgModule({
declarations: [
AppComponent,
HomeComponent,
HeaderComponent,
FooterComponent
],
imports: [
BrowserModule,
AppRoutingModule,
SharedModule,
VoituresModule
],
providers: [],
bootstrap: [HomeComponent]
})
export class AppModule { }
AppModule
HomeComponent
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
48
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
VoituresComponent
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
49
<div class="row">
<div class="col-4">
<app-voiture-list></app-voiture-list>
</div>
<div class="col-8">
<router-outlet></router-outlet>
</div>
</div>
import { Component, OnInit } from '@angular/core
';
@Component({
selector: 'app-voitures',
templateUrl: './voitures.component.html',
styleUrls: ['./voitures.component.css']
})
export class VoituresComponent implements OnInit
{
constructor() { }
ngOnInit(): void {
}
}
Routage et navigation
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
50
HomeComponent
Header
VoitureComponent
VoitureList
VoitureItem
Router
VoitureDetailVoitureStart VoitureEdit
Router
PageNotFound
Footer/voitures /**
/voitures /voitures/:id
/voitures/edit/:id
/voitures/new
Routes imbriqués
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
51
HomeComponent
Header
VoitureComponent
VoitureList
VoitureItem
Router
VoitureDetailVoitureStart VoitureEdit
Router
PageNotFound
Footer/voitures /**
/ /:id
/edit/:id
/new
Routes imbriqués
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
52
const appRoutes: Routes=[
{path: '', redirectTo: 'voitures', pathMatch:'full’},
{
path:'voitures’,
component: VoituresComponent,
Children: [
{ path: '', component: VoitureStartComponent},
{ path: 'new’, component: VoitureEditComponent},
{ path: ':id', component: VoitureDetailComponent},
{ path: 'edit/:id',component: VoitureEditComponent,}
]
},
{path: '**', component: PageNotFoundComponent}
];
Routes imbriqués
 Les routes imbriqués permettent de factoriser les
chemins
 En harmonie avec l’aspect hiérarchique des
composants: un composant héberge un ou plusieurs
composants
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
53
Routes par module
 Une moyenne ou grande application Angular
possède plusieurs modules de fonctionnalités
 Le module principal de routage sera trop chargé
 Solution: déléguer une partie de la gestion des
routes pour chaque module de fonctionnalités
 Chaque module de fonctionnalités gère ses propres
routes
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
54
Routes par module
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
55
Voitures
AppModule
SharedModule
AppRouting
VoituresRouting
Routes par module: AppRouting
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
56
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
const appRoutes: Routes=[
{path: '', redirectTo: 'voitures', pathMatch:'full'},
{path: '**', component: PageNotFoundComponent}
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [RouterModule]
})
export class AppRoutingModule{
}
Routes par module: VoituresRouting
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
57
...
const VoituresRoutes: Routes=[
{
path:'voitures', component:VoituresComponent,
children:[
{ path: '', component: VoitureStartComponent
},
{ path: 'new’, component: VoitureEditComponent
},
{ path: ':id', component: VoitureDetailComponent,
},
{ path: 'edit/:id’, component: VoitureEditComponent,
}
]
}
];
@NgModule({
imports: [
RouterModule.forChild(VoituresRoutes)
],
exports: [RouterModule]
})
export class VoituresRoutingModule { }
Routes par module: AppModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
58
...
@NgModule({
declarations: [
HomeComponent,
HeaderComponent,
FooterComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
SharedModule,
VoituresModule,
AppRoutingModule
],
bootstrap: [HomeComponent]
})
export class AppModule { }
Il faut respecter cet ordre
d’importation pour que
Angular puisse construire un
table de routage global
fonctionnel
Communication
entre composants
59
Communication entre composants
 La communication entre les composants fait partie
de l’architecture de l’application.
 Elle obéit à des règles stricts afin de:
 Optimiser les relations entre les composants
 garantir la cohérence de l’état de l’application
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
60
Communication entre composants
 Les flux de données
passent dans un seul sens
 La communication entre
service et composant
smart est réactive
 La communication d’un
composant smart vers un
composant dumb utilise le
décorateur @input
 Un composant dumb peut
notifier son père smart
 Pas de communication
direct entre composants
homologues
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
61
Service
Composant
smart
Composant
dumb
observable
@input @output
Composant
smart
62
ISETSidiBouzid:AngularAvancé-MDW2019/2020
VoituresService
VoituresList
VoitureItem
@Input() voiture: Voiture;
<img [src]="voiture.photo">
this.voitureService.getVoitures().subscribe(v =>{
this.voitures=v;
});
<app-voiture-item *ngFor="let v of voitures"
[voiture]="v">
</app-voiture-item>
getVoitures():Observable<Voiture[]>{
return this.http.get<Voiture[]>(this.baseURL);
}
Observable<Voiture[]>
@input
63
ISETSidiBouzid:AngularAvancé-MDW2019/2020
VoituresService
VoituresList VoitureEdit
this.voitureService
.postVoiture(this.voiture)
.subscribe(
v => {
this.voiture={};
formulaire.reset()
}
);
postVoiture(voiture: Voiture): Observable<Voiture>{
return this.http.post<Voiture>(this.baseURL, voiture).pipe(
tap(v => this.notifyVoitureChanged()))}
1
notifyVoitureChanged(){
this.getVoitures().subscribe(
voitures => this.voitureChanged.next(voitures))
}
voitureChanged=new Subject<Voiture[]>();
2
3
this.voitureService.voitureChanged
.subscribe(
(voitures :Voiture[]) => {
this.voitures=voitures
}
);
4 Notification réactive du modif Ajout/Modif voiture
Les Routes: Resolvers
64
Problématique
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
65
voiture 1
voiture 2
voiture 3
VoituresList VoitureDetails
VoituresComponent
?
Solution: Resolver
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
66
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
voiture 1
voiture 2
voiture 3
VoituresList
VoitureDetails
Router
/1
Voiture
Resolver
Voiture
Service
ActivatedRouteSnapshot
getVoiture(1) Observable<Voiture>
Observable<Voiture>
voiture
1
Activated
Route
(data)
VoitureResolver: code source
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
67
@Injectable({ providedIn: 'root' })
export class VoitureResolver implements Resolve<Voiture> {
constructor(private voitureService: VoituresService){}
resolve(route: ActivatedRouteSnapshot): Observable<Voiture> {
let id=route.paramMap.get('id’);
if(id!=null){
return this.voitureService.getVoiture(+id);
}
else{
return null;
}
}
}
VoitureRouting: update
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
68
const VoituresRoutes: Routes=[
{
path:'voitures',
component:VoituresComponent,
children:[
{
path: '',
component: VoitureStartComponent
},
{
path: 'new',
component: VoitureEditComponent
},
{
path: ':id',
component: VoitureDetailComponent,
resolve:{
voiture: VoitureResolver
}
},
{
path: 'edit/:id',
component: VoitureEditComponent,
resolve:{
voiture: VoitureResolver
}
}
]
}
];
VoitureDetail
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
69
export class VoitureDetailComponent implements OnInit {
voiture : Voiture;
isLogged: boolean;
constructor(private voitureService: VoituresService,
private router: Router,
private route: ActivatedRoute,
) { }
ngOnInit(): void {
this.route.data.subscribe(
(data)=>this.voiture=data['voiture']
);
}
}
Sécurité
70
Sécurité: Introduction
 Généralement une application web contient:
 Des cas d’utilisations public
 D’autres fonctionnalités privées, nécessitant une
authentification
 Exemple: Notre application de gestion de voitures
est composée de:
 une partie publique: Affichage des voitures
 Une partie privée: Ajout, Modification, suppression de
voitures
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
71
Authentification: JWT(JSON Web Token)
 Les deux parties Frontend et backend sont découplées
 La communication est sans état (statless <> statefull)
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
72
Application
Angular
Backend
username, password
Jeton JWT
Requete +Jeton
Réponse
 Un jeton possède une durée de vie
 Lorsque cette durée est expirée, il faut renouveler l’authentification
Authentification
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
73
AuthComponent AuthService
user
Backend
POST /authenticate
user
jetonBehaviorSubject
jeton
Apres Authentification: Interceptor
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
74
VoitureService
POST /voitures
V
AuthInterceptor
POST /voitures
V
jeton
AuthService
jeto
n
jeton
subscribe
Backend
Sécuriser les routes: AuthGard
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
75
voiture 1
voiture 2
voiture 3
VoituresList
Nouvelle voiture Router
AuthGard
Service
canActivate
Auth
Service
Authorisation
EditComponent
Démarche
 Créer un module pour l’authentification AuthModule
 Créer les deux entités User et Jeton
 Créer le service AuthService pour gérer l’authentification
 Créer le composant AuthComponent
 Mettre à jour AppRoutingModule: ajouter la route vers
AuthComponent
 Créer le service AuthInterceptor permettant de modifier
chaque requête http sortante en lui ajoutant le jeton
 Créer le service AuthGard pour garder les routes privées
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
76
AuthModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
77
Voitures
AppModule
SharedModule
AppRouting
VoituresRouting
AuthModule
Les entités User et Jeton
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
78
export class User{
constructor(public username:String,
public password: String
){}
}
export class Jeton{
constructor(public jwt:String){}
}
Exercice
 Analyser le code source de l’application pour
terminer les étapes restantes
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
79
Optimisation
LAZY LOADING
80
Introduction
 Une grande application Angular est composée de plusieurs
modules de fonctionnalités
 En production, le chargement de l’application au début peut
prendre beaucoup de temps
 Idée:
 Au début, charger uniquement les modules nécessaires
 Les autres modules de fonctionnalités seront chargés à la demande
 Cette technique s’appelle chargement paresseux, ou Lazy-loading
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
81
Lazy-loading: Exemple
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
82
AppModule
SharedModule
AppRoutingAuthModule
Lazy-loading: Exemple
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
83
Voitures
AppModule
SharedModule
AppRouting
VoituresRouting
AuthModule
Lazy-loading
Démarche
 Mettre à jour AppRoutingModule
 Mettre à jour VoituresRoutingModule
 Mettre à jour AppModule: supprimer la dépendance
VoitureModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
84
AppRoutingModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
85
const appRoutes: Routes=[
{path: '', redirectTo: 'voitures', pathMatch:'full'},
{
path:'voitures’,
loadChildren: ()=>import('./voitures/voitures.module').then(m =>m.VoituresModule)
}
{path:'login', component:AuthComponent},
{path: '**', component: PageNotFoundComponent}
];
VoituresRoutingModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
86
const VoituresRoutes: Routes=[
{
path:’voitures’,
component:VoituresComponent,
children:[
{
path: '',
component: VoitureStartComponent
},
{ path: 'new', component: VoitureEditComponent},
{ path: ':id', component: VoitureDetailComponent,
resolve:{voiture: VoitureResolver}
},
{ path: 'edit/:id', component: VoitureEditComponent,
resolve:{ voiture: VoitureResolver}
}
]
}
];
AppModule
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
87
import { VoituresModule } from "./voitures/voitures.module";
imports: [
BrowserModule,
SharedModule,
AuthModule,
VoituresModule,
AppRoutingModule,
HttpClientModule
]
Exercice
 Effectuer les changement nécessaires pour rendre
le chargement du module AuthModule Lasy
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
88
Preloading Strategy
 Avec lazy-loading, le module sera chargé du serveur à la
demande de l’utilisateur
 Souvent ce module est assez volumineux, donc
l’utilisateur va sentir la latence du chargement
 Solution: commencer le chargement des modules lazy
juste après le chargement du noyau
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
89
Preloading Strategy
ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
90
AppRoutingModule
import { Routes, RouterModule, PreloadAllModules } from "@angular/router";
imports: [
RouterModule.forRoot(appRoutes, {preloadingStrategy: PreloadAllModules })
],

Contenu connexe

Tendances

Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)ENSET, Université Hassan II Casablanca
 
Technologies sur angular.pptx
Technologies sur angular.pptxTechnologies sur angular.pptx
Technologies sur angular.pptxIdrissaDembl
 
Rapport application web (Spring BOOT,angular4) et mobile(ionc3) gestion des a...
Rapport application web (Spring BOOT,angular4) et mobile(ionc3) gestion des a...Rapport application web (Spring BOOT,angular4) et mobile(ionc3) gestion des a...
Rapport application web (Spring BOOT,angular4) et mobile(ionc3) gestion des a...MOHAMMED MOURADI
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications JavaAntoine Rey
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPYouness Boukouchi
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring bootAntoine Rey
 

Tendances (20)

Support JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVCSupport JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVC
 
Cours 2 les composants
Cours 2 les composantsCours 2 les composants
Cours 2 les composants
 
Angular
AngularAngular
Angular
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
 
Technologies sur angular.pptx
Technologies sur angular.pptxTechnologies sur angular.pptx
Technologies sur angular.pptx
 
Rapport application web (Spring BOOT,angular4) et mobile(ionc3) gestion des a...
Rapport application web (Spring BOOT,angular4) et mobile(ionc3) gestion des a...Rapport application web (Spring BOOT,angular4) et mobile(ionc3) gestion des a...
Rapport application web (Spring BOOT,angular4) et mobile(ionc3) gestion des a...
 
Support NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDBSupport NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDB
 
Support JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.YoussfiSupport JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.Youssfi
 
Introduction à Angular
Introduction à AngularIntroduction à Angular
Introduction à Angular
 
Cours design pattern m youssfi partie 7 facade bridge flyweight
Cours design pattern m youssfi partie 7 facade bridge flyweightCours design pattern m youssfi partie 7 facade bridge flyweight
Cours design pattern m youssfi partie 7 facade bridge flyweight
 
Support de cours technologie et application m.youssfi
Support de cours technologie et application m.youssfiSupport de cours technologie et application m.youssfi
Support de cours technologie et application m.youssfi
 
DART.pptx
DART.pptxDART.pptx
DART.pptx
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications Java
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSP
 
spring-boot-fr.pdf
spring-boot-fr.pdfspring-boot-fr.pdf
spring-boot-fr.pdf
 
Support Java Avancé Troisième Partie
Support Java Avancé Troisième PartieSupport Java Avancé Troisième Partie
Support Java Avancé Troisième Partie
 
Cours design pattern m youssfi partie 4 composite
Cours design pattern m youssfi partie 4 compositeCours design pattern m youssfi partie 4 composite
Cours design pattern m youssfi partie 4 composite
 
Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)
 
Présentation Angular 2
Présentation Angular 2 Présentation Angular 2
Présentation Angular 2
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring boot
 

Similaire à Angular Avancé

Partie 2: Angular
Partie 2: AngularPartie 2: Angular
Partie 2: AngularHabib Ayad
 
CV_JDIAli
CV_JDIAliCV_JDIAli
CV_JDIAliAliJdi
 
Societe generale-uiux
Societe generale-uiuxSociete generale-uiux
Societe generale-uiuxSalma EL OUR
 
La Duck Conf - "Quelle place pour le no code/low code dans les entreprises ?"
La Duck Conf - "Quelle place pour le no code/low code dans les entreprises ?"La Duck Conf - "Quelle place pour le no code/low code dans les entreprises ?"
La Duck Conf - "Quelle place pour le no code/low code dans les entreprises ?"OCTO Technology
 
Rapport du Projet de Fin d'année Génie informatique ENSA AGADIR
Rapport du Projet de Fin d'année Génie informatique ENSA AGADIRRapport du Projet de Fin d'année Génie informatique ENSA AGADIR
Rapport du Projet de Fin d'année Génie informatique ENSA AGADIRAHMEDAKHACHKHOUCH
 
La Duck Conf - "Mon DSI veut une MEP par jour, comment faire de l'architectur...
La Duck Conf - "Mon DSI veut une MEP par jour, comment faire de l'architectur...La Duck Conf - "Mon DSI veut une MEP par jour, comment faire de l'architectur...
La Duck Conf - "Mon DSI veut une MEP par jour, comment faire de l'architectur...OCTO Technology
 
IBM Bluemix Paris meetup - #PG4D - 20160914-3
IBM Bluemix Paris meetup - #PG4D -  20160914-3IBM Bluemix Paris meetup - #PG4D -  20160914-3
IBM Bluemix Paris meetup - #PG4D - 20160914-3IBM France Lab
 
Dossier de creation_entreprise_v0.90
Dossier de creation_entreprise_v0.90Dossier de creation_entreprise_v0.90
Dossier de creation_entreprise_v0.90Arnold Stellio
 
Visual studio 2017 Launch keynote - Afterworks@Noumea
Visual studio 2017 Launch keynote - Afterworks@NoumeaVisual studio 2017 Launch keynote - Afterworks@Noumea
Visual studio 2017 Launch keynote - Afterworks@NoumeaJulien Chable
 
OCTO Talks - State of the art Architecture dans les frontend web
OCTO Talks - State of the art Architecture dans les frontend webOCTO Talks - State of the art Architecture dans les frontend web
OCTO Talks - State of the art Architecture dans les frontend webOCTO Technology
 
Meetup Angular Paris - Feature Modules
Meetup Angular Paris - Feature ModulesMeetup Angular Paris - Feature Modules
Meetup Angular Paris - Feature ModulesDaniel Djordjevic
 
L'histoire d'une infrastructure itérative
L'histoire d'une infrastructure itérativeL'histoire d'une infrastructure itérative
L'histoire d'une infrastructure itérativeFrançois Xavier Vende
 
Application de gestion, suivi,et de sécurité des chantiers en temps réels.
Application  de gestion, suivi,et de sécurité des chantiers en temps réels.Application  de gestion, suivi,et de sécurité des chantiers en temps réels.
Application de gestion, suivi,et de sécurité des chantiers en temps réels.Sabri El gharbi El yahmadi
 

Similaire à Angular Avancé (20)

Partie 2: Angular
Partie 2: AngularPartie 2: Angular
Partie 2: Angular
 
CV_JDIAli
CV_JDIAliCV_JDIAli
CV_JDIAli
 
Societe generale-uiux
Societe generale-uiuxSociete generale-uiux
Societe generale-uiux
 
CV_Karim_SOUISSI_VF
CV_Karim_SOUISSI_VFCV_Karim_SOUISSI_VF
CV_Karim_SOUISSI_VF
 
La Duck Conf - "Quelle place pour le no code/low code dans les entreprises ?"
La Duck Conf - "Quelle place pour le no code/low code dans les entreprises ?"La Duck Conf - "Quelle place pour le no code/low code dans les entreprises ?"
La Duck Conf - "Quelle place pour le no code/low code dans les entreprises ?"
 
Rapport du Projet de Fin d'année Génie informatique ENSA AGADIR
Rapport du Projet de Fin d'année Génie informatique ENSA AGADIRRapport du Projet de Fin d'année Génie informatique ENSA AGADIR
Rapport du Projet de Fin d'année Génie informatique ENSA AGADIR
 
Test&Value GET YOUR WAY
Test&Value GET YOUR WAYTest&Value GET YOUR WAY
Test&Value GET YOUR WAY
 
cours-gratuit.com--id-4422.pdf
cours-gratuit.com--id-4422.pdfcours-gratuit.com--id-4422.pdf
cours-gratuit.com--id-4422.pdf
 
La Duck Conf - "Mon DSI veut une MEP par jour, comment faire de l'architectur...
La Duck Conf - "Mon DSI veut une MEP par jour, comment faire de l'architectur...La Duck Conf - "Mon DSI veut une MEP par jour, comment faire de l'architectur...
La Duck Conf - "Mon DSI veut une MEP par jour, comment faire de l'architectur...
 
Test&Value GET YOUR WAY
Test&Value GET YOUR WAYTest&Value GET YOUR WAY
Test&Value GET YOUR WAY
 
IBM Bluemix Paris meetup - #PG4D - 20160914-3
IBM Bluemix Paris meetup - #PG4D -  20160914-3IBM Bluemix Paris meetup - #PG4D -  20160914-3
IBM Bluemix Paris meetup - #PG4D - 20160914-3
 
TP GWT JDEV 2015
TP GWT JDEV 2015TP GWT JDEV 2015
TP GWT JDEV 2015
 
Dossier de creation_entreprise_v0.90
Dossier de creation_entreprise_v0.90Dossier de creation_entreprise_v0.90
Dossier de creation_entreprise_v0.90
 
CV REBAI Hamida
CV REBAI HamidaCV REBAI Hamida
CV REBAI Hamida
 
Visual studio 2017 Launch keynote - Afterworks@Noumea
Visual studio 2017 Launch keynote - Afterworks@NoumeaVisual studio 2017 Launch keynote - Afterworks@Noumea
Visual studio 2017 Launch keynote - Afterworks@Noumea
 
OCTO Talks - State of the art Architecture dans les frontend web
OCTO Talks - State of the art Architecture dans les frontend webOCTO Talks - State of the art Architecture dans les frontend web
OCTO Talks - State of the art Architecture dans les frontend web
 
CV
CVCV
CV
 
Meetup Angular Paris - Feature Modules
Meetup Angular Paris - Feature ModulesMeetup Angular Paris - Feature Modules
Meetup Angular Paris - Feature Modules
 
L'histoire d'une infrastructure itérative
L'histoire d'une infrastructure itérativeL'histoire d'une infrastructure itérative
L'histoire d'une infrastructure itérative
 
Application de gestion, suivi,et de sécurité des chantiers en temps réels.
Application  de gestion, suivi,et de sécurité des chantiers en temps réels.Application  de gestion, suivi,et de sécurité des chantiers en temps réels.
Application de gestion, suivi,et de sécurité des chantiers en temps réels.
 

Angular Avancé

  • 1. Angular Avancé INSTITUT SUPÉRIEUR DES ÉTUDES TECHNOLOGIQUES DE SIDI BOUZID ENSEIGNANT: NIZAR MAATOUG GROUPE: MDW2 2019-2020
  • 2. Résultats ➢ Développer une application Angular en suivant les bonnes pratiques ➢ Consolider et pratiquer les concepts de base ➢ Optimiser les performances d’une application Angular ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 2
  • 3. Application de Gestion de voitures  On souhaite développer une application de gestion de voitures.  Chaque voiture est caractérisée par:  un identifiant  Une marque  Un modèle  une couleur  L’application permet de:  Consulter les voitures  Ajouter une nouvelle voiture  Mettre à jour une voiture  Supprimer une voiture ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 3
  • 4. Démo & code source  Démo: https://www.youtube.com/watch?v=ddU92H6fazk  Code source : https://github.com/nizar-maatoug/gestion-voitures ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 4
  • 5. Environnement de développement  Bibliothèques javascript Node JS  Angular CLI  Environnement de développement intégré VS code ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 5
  • 6. Création du projet  ng new gestion-voitures --routing  Installation de bootstrap:  npm install -- save bootstrap  npm install --save jquery  npm install --save popper.js ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 6
  • 7. Mise à jour angular.json ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 7
  • 9. Architecture de l’application  Comment découper mon application en modules ?  Combien de modules dois-je créer ?  Où placer mes composants, comme la barre de navigation par exemple ?  Dans quel dossier regrouper mes services ?  Comment modéliser mes entités avec des classes TypeScript ?  Ou placer les fichiers nécessaires pour l’authentification ? ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 9
  • 10. 10 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 ?
  • 11. Architecture: Rappel  Une application Angular est structurée en modules  Un module regroupe logiquement des composants graphiques, des directives, des pipes et d’autres sous-modules.  Un module fournit des services  Par défaut, une application Angular contient un seul module principal AppModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 11
  • 12. 12 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 AppModule AppComponent Nav-barComponent FooterComponent VoitureComponent ListeVoitureComponent Pour une petite application, le module principal AppModule est suffisant.
  • 13. 13 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 AppModule AppComponent Nav-barComponent FooterComponent VoitureComponent ListeVoitureComponent . . . Mais pour les moyennes et grandes applications, AppModule sera très chargé, donc il est difficile de faire évoluer l’application, de la maintenir ou même de repérer un fichier
  • 14. 14 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 AppModule AppComponent Nav-barComponent FooterComponent VoitureModule VoitureComponent ListeVoitureComponent . . . DetailVoitureComponent EditVoitureComponent Il faut penser à organiser l’application par module pour chaque fonctionnalité: exemple: gestion voiture
  • 15. 15 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 AppModule Fonctionnalité1 Fonctionnalité2 Fonctionnalité3
  • 16. SharedModule: Minimiser les importations  Souvent, des modules, des composants et des directives sont sollicités par plusieurs composants dans différents modules.  Une bonne pratique consiste à regrouper ces dépendances dans un seul module appelé SharedModule (ou module partagé) ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 16
  • 17. 17 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 Fonctionnalité1 Fonctionnalité2 Fonctionnalité3 Des importations répétitives dans plusieurs modules
  • 18. 18 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 Fonctionnalité1 Fonctionnalité2 Fonctionnalité3 SharedModule exports [ ] Exemple: CommonModule un module angular qui exporte les directives de base: NgIF, NgFor,… Solution: Factoriser ces importations répétitives dans un module unique: SharedModule
  • 19. 19 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 Fonctionnalité1 Fonctionnalité2 Fonctionnalité3 SharedModule exports [ ] Exemple: CommonModule un module angular qui exporte les directives de base: NgIF, NgFor,… Solution: Factoriser ces importations répétitives dans un module unique: SharedModule
  • 21. Démarche  Créer le SharedModule  Créer le module fonctionnel VoituresModules  Importer le module SharedModule dans VoituresModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 21
  • 22. Créer le module Shared ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 22 Générer le module SharedModule
  • 23. Exporter CommonModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 23 Exporter le CommonModule pour le rendre disponible aux modules qui importent le SharedModule
  • 24. Créer le module Voitures ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 24 Générer le module VoituresModule
  • 25. VoituresModule: importer Shared ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 25 Importer le module SharedModule
  • 26. Architecture initiale ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 26 AppModule VoituresModule SharedModule AppRoutingModule❑ C’est l’architecture initiale de notre projet ❑ Elle peut évoluer au cours du développement ❑ Mais elle est flexible, évolutive et rend notre projet facilement maintenable
  • 27. Exercice  Effectuer les mises à jour nécessaires afin d’obtenir l’architecture suivante ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 27 AppModule VoituresModule SharedModule AppRoutingModule
  • 28. Solution ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 28
  • 29. Les services  Un service est une classe TypeScript qui implémente une partie de la logique métier de l’application  Exemple: Calcul âge, ajout d’une voiture côté serveur,...  Permet aussi de mémoriser et partager l’état de l’application entre plusieurs composants  Exemple: mémoriser et partager la liste des voitures  Il faut bien gérer l’état de l’application:  Garantir la cohérence de l’application  Synchroniser les composants ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 29
  • 30. 30 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 AppModule Fonctionnalité1 Fonctionnalité2 Fonctionnalité3 Service Un service fourni par le AppModule sera unique dans toute l’application: une seule instance (Singleton)
  • 31. 31 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 AppModule Fonctionnalité1 Fonctionnalité2 Fonctionnalité3 Service Un service fourni par un module sera unique et accessible à tous les sous-modules et les composants de ce module
  • 32. 32 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 Module Composant Sous-Composant Service Un service fourni par un composant sera accessible uniquement dans le composant lui-même et ses composants fils
  • 33. Bonne pratique: service  Dans la grande majorité des cas, un service doit avoir une seule instance dans l’application  Dans ce cas, il doit être fourni par le AppModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 33 @Injectable({ providedIn: 'root' }) export class VoituresService {…} root: fourni par le module principal AppModule
  • 34. partie Backend ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 34 client Serveur Application Angular Application Spring (Java) BD GET URL/voitures Retourne liste voitures GET URL/voitures/1 Retourne voiture id=1 POST URL/voitures V OK V PUT URL/voitures V OK V DELETE URL/voitures/2 OK
  • 35. VoituresService (1/2) ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 35 import { HttpClient} from "@angular/common/http"; import { Observable, Subject } from 'rxjs’; import { Voiture } from "./model/voiture.model"; import { tap } from 'rxjs/operators’; @Injectable({ providedIn: 'root’ }) export class VoituresService { private baseURL="http://localhost:8080/voitures"; voitureChanged=new Subject<Voiture[]>(); constructor(private http: HttpClient) { } /**Get voitures */ getVoitures():Observable<Voiture[]>{ return this.http.get<Voiture[]>(this.baseURL); } /**Get voiture */ getVoiture(id:number):Observable<Voiture>{ const url= this.baseURL+ '/'+ id; return this.http.get<Voiture>(url); } /**Post voiture */ postVoiture(voiture: Voiture): Observable<Voiture>{ return this.http.post<Voiture>(this.baseURL, voiture).pipe( tap(v => this.notifyVoitureChanged()) ) }
  • 36. VoituresService (2/2) ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 36 /**PUT: mettre à jour la voiture dans le serveur */ updateVoiture(voiture: Voiture): Observable<Voiture>{ return this.http.put<Voiture>(this.baseURL, voiture).pipe( tap(v => this.notifyVoitureChanged()) ); } /**DELETE: supprimer la voiture */ deleteVoiture(voiture: Voiture):Observable<String>{ console.log(voiture.id); return this.http.delete<String>(this.baseURL+'/'+voiture.id).pipe( tap(v => this.notifyVoitureChanged()) ); } notifyVoitureChanged(){ this.getVoitures().subscribe( voitures => this.voitureChanged.next(voitures) ) }
  • 37. Les composants: ARCHITECTURE ET BONNES PRATIQUES 37
  • 38. Angular : framework orienté composant  Angular est un framework orienté composant  Single Page Application (SPA): application web avec une seule page  L’unique page web est le socle d’une arborescence de composants  Problématique:  Comment structurer ces composants d’une façon optimale, maintenable, évolutive ?  Comment gérer la communication entre ces composants afin de garantir la cohérence et l’état de l’application? ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 38
  • 39.  Une application Angular est un assemblage de composants  Par analogie, les composants ressemble à des pièces de Lego 39 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020
  • 40. Types des composants ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 40 Composant de page Composant intelligent (smart) Composant idiot (dumb)  3 types de composants:  composant de page: conteneur d’une arborescence de composants, son rôle est de structurer les composants  Composant intelligent: communique avec les services  Composant idiot: moins de logique métier, il se charge d’afficher les données
  • 41. 41 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 FooterComponent : dumb HeaderComponent : Smart HomeComponent : page
  • 42. 42 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 voitureComponent: composant de page voitureListComponent: smart VoitureDetailComponent: smart VoitureItemComponent : dumb
  • 43. Arborescence des composants ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 43 HomeComponent Header VoitureComponent VoitureList VoitureItem Router VoitureDetailVoitureStart VoitureEdit Router PageNotFound Footer
  • 44.  Dans le module AppModule, création des composants:  HomeComponent  HeaderComponent  FooterComponent  PageNotFoundComponent  Dans le module VoitureModule, création des composants:  VoituresComponent  VoitureListComponent  VoitureItemComponent  VoitureStartComponent  VoitureDetailComponent ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 44 Manip: création des composants
  • 45. Manip: création des composants  ng g c home  ng g c header  ng g c footer  ng g c page-not-found  ng g c voitures --module=voitures  ng g c voitures/voiture-list --module=voitures  ng g c voitures/voiture-list/voiture-item –module=voitures  ng g c voitures/voiture-start --module=voitures  ng g c voitures/voiture-detail --module=voitures  ng g c voitures/voiture-edit --module=voitures ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 45 AppModule VoituresModule
  • 46. Résultats ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 46
  • 47. Home: composant principal ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 47 @NgModule({ declarations: [ AppComponent, HomeComponent, HeaderComponent, FooterComponent ], imports: [ BrowserModule, AppRoutingModule, SharedModule, VoituresModule ], providers: [], bootstrap: [HomeComponent] }) export class AppModule { } AppModule
  • 48. HomeComponent ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 48 <app-header></app-header> <router-outlet></router-outlet> <app-footer></app-footer> import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.css'] }) export class HomeComponent implements OnInit { constructor() { } ngOnInit() { } }
  • 49. VoituresComponent ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 49 <div class="row"> <div class="col-4"> <app-voiture-list></app-voiture-list> </div> <div class="col-8"> <router-outlet></router-outlet> </div> </div> import { Component, OnInit } from '@angular/core '; @Component({ selector: 'app-voitures', templateUrl: './voitures.component.html', styleUrls: ['./voitures.component.css'] }) export class VoituresComponent implements OnInit { constructor() { } ngOnInit(): void { } }
  • 50. Routage et navigation ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 50 HomeComponent Header VoitureComponent VoitureList VoitureItem Router VoitureDetailVoitureStart VoitureEdit Router PageNotFound Footer/voitures /** /voitures /voitures/:id /voitures/edit/:id /voitures/new
  • 51. Routes imbriqués ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 51 HomeComponent Header VoitureComponent VoitureList VoitureItem Router VoitureDetailVoitureStart VoitureEdit Router PageNotFound Footer/voitures /** / /:id /edit/:id /new
  • 52. Routes imbriqués ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 52 const appRoutes: Routes=[ {path: '', redirectTo: 'voitures', pathMatch:'full’}, { path:'voitures’, component: VoituresComponent, Children: [ { path: '', component: VoitureStartComponent}, { path: 'new’, component: VoitureEditComponent}, { path: ':id', component: VoitureDetailComponent}, { path: 'edit/:id',component: VoitureEditComponent,} ] }, {path: '**', component: PageNotFoundComponent} ];
  • 53. Routes imbriqués  Les routes imbriqués permettent de factoriser les chemins  En harmonie avec l’aspect hiérarchique des composants: un composant héberge un ou plusieurs composants ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 53
  • 54. Routes par module  Une moyenne ou grande application Angular possède plusieurs modules de fonctionnalités  Le module principal de routage sera trop chargé  Solution: déléguer une partie de la gestion des routes pour chaque module de fonctionnalités  Chaque module de fonctionnalités gère ses propres routes ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 54
  • 55. Routes par module ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 55 Voitures AppModule SharedModule AppRouting VoituresRouting
  • 56. Routes par module: AppRouting ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 56 import { NgModule } from "@angular/core"; import { Routes, RouterModule } from "@angular/router"; const appRoutes: Routes=[ {path: '', redirectTo: 'voitures', pathMatch:'full'}, {path: '**', component: PageNotFoundComponent} ]; @NgModule({ imports: [ RouterModule.forRoot(appRoutes) ], exports: [RouterModule] }) export class AppRoutingModule{ }
  • 57. Routes par module: VoituresRouting ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 57 ... const VoituresRoutes: Routes=[ { path:'voitures', component:VoituresComponent, children:[ { path: '', component: VoitureStartComponent }, { path: 'new’, component: VoitureEditComponent }, { path: ':id', component: VoitureDetailComponent, }, { path: 'edit/:id’, component: VoitureEditComponent, } ] } ]; @NgModule({ imports: [ RouterModule.forChild(VoituresRoutes) ], exports: [RouterModule] }) export class VoituresRoutingModule { }
  • 58. Routes par module: AppModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 58 ... @NgModule({ declarations: [ HomeComponent, HeaderComponent, FooterComponent, PageNotFoundComponent ], imports: [ BrowserModule, SharedModule, VoituresModule, AppRoutingModule ], bootstrap: [HomeComponent] }) export class AppModule { } Il faut respecter cet ordre d’importation pour que Angular puisse construire un table de routage global fonctionnel
  • 60. Communication entre composants  La communication entre les composants fait partie de l’architecture de l’application.  Elle obéit à des règles stricts afin de:  Optimiser les relations entre les composants  garantir la cohérence de l’état de l’application ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 60
  • 61. Communication entre composants  Les flux de données passent dans un seul sens  La communication entre service et composant smart est réactive  La communication d’un composant smart vers un composant dumb utilise le décorateur @input  Un composant dumb peut notifier son père smart  Pas de communication direct entre composants homologues ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 61 Service Composant smart Composant dumb observable @input @output Composant smart
  • 62. 62 ISETSidiBouzid:AngularAvancé-MDW2019/2020 VoituresService VoituresList VoitureItem @Input() voiture: Voiture; <img [src]="voiture.photo"> this.voitureService.getVoitures().subscribe(v =>{ this.voitures=v; }); <app-voiture-item *ngFor="let v of voitures" [voiture]="v"> </app-voiture-item> getVoitures():Observable<Voiture[]>{ return this.http.get<Voiture[]>(this.baseURL); } Observable<Voiture[]> @input
  • 63. 63 ISETSidiBouzid:AngularAvancé-MDW2019/2020 VoituresService VoituresList VoitureEdit this.voitureService .postVoiture(this.voiture) .subscribe( v => { this.voiture={}; formulaire.reset() } ); postVoiture(voiture: Voiture): Observable<Voiture>{ return this.http.post<Voiture>(this.baseURL, voiture).pipe( tap(v => this.notifyVoitureChanged()))} 1 notifyVoitureChanged(){ this.getVoitures().subscribe( voitures => this.voitureChanged.next(voitures)) } voitureChanged=new Subject<Voiture[]>(); 2 3 this.voitureService.voitureChanged .subscribe( (voitures :Voiture[]) => { this.voitures=voitures } ); 4 Notification réactive du modif Ajout/Modif voiture
  • 65. Problématique ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 65 voiture 1 voiture 2 voiture 3 VoituresList VoitureDetails VoituresComponent ?
  • 66. Solution: Resolver ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 66 ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 voiture 1 voiture 2 voiture 3 VoituresList VoitureDetails Router /1 Voiture Resolver Voiture Service ActivatedRouteSnapshot getVoiture(1) Observable<Voiture> Observable<Voiture> voiture 1 Activated Route (data)
  • 67. VoitureResolver: code source ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 67 @Injectable({ providedIn: 'root' }) export class VoitureResolver implements Resolve<Voiture> { constructor(private voitureService: VoituresService){} resolve(route: ActivatedRouteSnapshot): Observable<Voiture> { let id=route.paramMap.get('id’); if(id!=null){ return this.voitureService.getVoiture(+id); } else{ return null; } } }
  • 68. VoitureRouting: update ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 68 const VoituresRoutes: Routes=[ { path:'voitures', component:VoituresComponent, children:[ { path: '', component: VoitureStartComponent }, { path: 'new', component: VoitureEditComponent }, { path: ':id', component: VoitureDetailComponent, resolve:{ voiture: VoitureResolver } }, { path: 'edit/:id', component: VoitureEditComponent, resolve:{ voiture: VoitureResolver } } ] } ];
  • 69. VoitureDetail ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 69 export class VoitureDetailComponent implements OnInit { voiture : Voiture; isLogged: boolean; constructor(private voitureService: VoituresService, private router: Router, private route: ActivatedRoute, ) { } ngOnInit(): void { this.route.data.subscribe( (data)=>this.voiture=data['voiture'] ); } }
  • 71. Sécurité: Introduction  Généralement une application web contient:  Des cas d’utilisations public  D’autres fonctionnalités privées, nécessitant une authentification  Exemple: Notre application de gestion de voitures est composée de:  une partie publique: Affichage des voitures  Une partie privée: Ajout, Modification, suppression de voitures ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 71
  • 72. Authentification: JWT(JSON Web Token)  Les deux parties Frontend et backend sont découplées  La communication est sans état (statless <> statefull) ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 72 Application Angular Backend username, password Jeton JWT Requete +Jeton Réponse  Un jeton possède une durée de vie  Lorsque cette durée est expirée, il faut renouveler l’authentification
  • 73. Authentification ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 73 AuthComponent AuthService user Backend POST /authenticate user jetonBehaviorSubject jeton
  • 74. Apres Authentification: Interceptor ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 74 VoitureService POST /voitures V AuthInterceptor POST /voitures V jeton AuthService jeto n jeton subscribe Backend
  • 75. Sécuriser les routes: AuthGard ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 75 voiture 1 voiture 2 voiture 3 VoituresList Nouvelle voiture Router AuthGard Service canActivate Auth Service Authorisation EditComponent
  • 76. Démarche  Créer un module pour l’authentification AuthModule  Créer les deux entités User et Jeton  Créer le service AuthService pour gérer l’authentification  Créer le composant AuthComponent  Mettre à jour AppRoutingModule: ajouter la route vers AuthComponent  Créer le service AuthInterceptor permettant de modifier chaque requête http sortante en lui ajoutant le jeton  Créer le service AuthGard pour garder les routes privées ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 76
  • 77. AuthModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 77 Voitures AppModule SharedModule AppRouting VoituresRouting AuthModule
  • 78. Les entités User et Jeton ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 78 export class User{ constructor(public username:String, public password: String ){} } export class Jeton{ constructor(public jwt:String){} }
  • 79. Exercice  Analyser le code source de l’application pour terminer les étapes restantes ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 79
  • 81. Introduction  Une grande application Angular est composée de plusieurs modules de fonctionnalités  En production, le chargement de l’application au début peut prendre beaucoup de temps  Idée:  Au début, charger uniquement les modules nécessaires  Les autres modules de fonctionnalités seront chargés à la demande  Cette technique s’appelle chargement paresseux, ou Lazy-loading ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 81
  • 82. Lazy-loading: Exemple ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 82 AppModule SharedModule AppRoutingAuthModule
  • 83. Lazy-loading: Exemple ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 83 Voitures AppModule SharedModule AppRouting VoituresRouting AuthModule Lazy-loading
  • 84. Démarche  Mettre à jour AppRoutingModule  Mettre à jour VoituresRoutingModule  Mettre à jour AppModule: supprimer la dépendance VoitureModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 84
  • 85. AppRoutingModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 85 const appRoutes: Routes=[ {path: '', redirectTo: 'voitures', pathMatch:'full'}, { path:'voitures’, loadChildren: ()=>import('./voitures/voitures.module').then(m =>m.VoituresModule) } {path:'login', component:AuthComponent}, {path: '**', component: PageNotFoundComponent} ];
  • 86. VoituresRoutingModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 86 const VoituresRoutes: Routes=[ { path:’voitures’, component:VoituresComponent, children:[ { path: '', component: VoitureStartComponent }, { path: 'new', component: VoitureEditComponent}, { path: ':id', component: VoitureDetailComponent, resolve:{voiture: VoitureResolver} }, { path: 'edit/:id', component: VoitureEditComponent, resolve:{ voiture: VoitureResolver} } ] } ];
  • 87. AppModule ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 87 import { VoituresModule } from "./voitures/voitures.module"; imports: [ BrowserModule, SharedModule, AuthModule, VoituresModule, AppRoutingModule, HttpClientModule ]
  • 88. Exercice  Effectuer les changement nécessaires pour rendre le chargement du module AuthModule Lasy ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 88
  • 89. Preloading Strategy  Avec lazy-loading, le module sera chargé du serveur à la demande de l’utilisateur  Souvent ce module est assez volumineux, donc l’utilisateur va sentir la latence du chargement  Solution: commencer le chargement des modules lazy juste après le chargement du noyau ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 89
  • 90. Preloading Strategy ISET Sidi Bouzid: Angular Avancé-MDW 2019/2020 90 AppRoutingModule import { Routes, RouterModule, PreloadAllModules } from "@angular/router"; imports: [ RouterModule.forRoot(appRoutes, {preloadingStrategy: PreloadAllModules }) ],