0% ont trouvé ce document utile (0 vote)
53 vues157 pages

Concepts de base d'Angular

Concepts de base Angular

Transféré par

abouqora
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
53 vues157 pages

Concepts de base d'Angular

Concepts de base Angular

Transféré par

abouqora
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Angular : concepts de base

1 / 102
Plan

1 Introduction

2 Liaison template/classe (composant)


Interpolation {{ ... }}
Property binding [ ... ]
Event binding ( ... )

3 Directives Angular
*ngFor
*ngIf
ngSwitch
ngPlural
ngStyle
ngClass

2 / 102
Plan

4 Control Flow Syntax


@for
@empty
@if
@else
@switch

5 Valeurs réactives
signal
computed
effect

3 / 102
Introduction

Angular

4 modes de liaison (binding) avec Angular

One way binding


H I ©
UEL
Property binding [ ... ]
Interpolation {{ ... }} L M
O
e
Event binding ( r...
f E
A ch )

Two way© binding [( ... )]

4 / 102
Introduction

Angular

Le fichier app.component.ts Le fichier app.component.html

import { Component } from '@angular/core'; <div style="text-align:center">


<h1>
@Component({ Welcome to {{ title }}!
selector: 'app-root', </h1>
templateUrl: './app.component.html', ...
styleUrls: ['./app.component.css'] </div>
})
export class AppComponent {
title = 'cours-angular';
}

5 / 102
Introduction

Angular

Le fichier app.component.ts Le fichier app.component.html

import { Component } from '@angular/core'; <div style="text-align:center">


<h1>
@Component({ Welcome to {{ title }}!
selector: 'app-root', </h1>
templateUrl: './app.component.html', ...
styleUrls: ['./app.component.css'] </div>
})
export class AppComponent {
title = 'cours-angular';
}

{{ Interpolation }}

Welcome to {{ title }} ! :
title sera remplacé par sa valeur dans app.component.ts

5 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular

Objectif : afficher les attributs et les valeurs sous forme d’une liste HTML

H I ©
Créer un répertoire classes dans app où toutes les classes seront stockées.
EL
OU
Créer une classe Stagiaire avec les attributs num, nom et prénom.
M
f E
Créer un objet de cette classe dansLapp.component.ts
c e
hcetr objet sous forme de liste dans
© A
Afficher les valeurs
app.component.html
de

6 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular

On peut aussi utiliser la commande

ng generate class classes/stagiaire

7 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular

On peut aussi utiliser la commande

ng generate class classes/stagiaire

Pour générer une classe sans le fichier de test (.spec.ts)

ng generate class classes/stagiaire --skip-tests=true

7 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular

On peut aussi utiliser la commande

ng generate class classes/stagiaire

Pour générer une classe sans le fichier de test (.spec.ts)

ng generate class classes/stagiaire --skip-tests=true

Remarque

L’option --skip-tests=true peut être utilisée avec la commande generate quel


que soit l’élément généré.

7 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Contenu de stagiaire.ts

export class Stagiaire {


constructor(private _num?: number, private _nom?: string, private
_prenom?: string) { }

get num(): number | undefined {


return this._num;
}
set num(_num: number | undefined) {
this._num = _num;
}
get nom(): string | undefined {
return this._nom;
}
set nom(_nom: string | undefined) {
this._nom = _nom;
}
get prenom(): string | undefined {
return this._prenom;
}
set prenom(_prenom: string | undefined) {
this._prenom = _prenom;
}
}

8 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular

Créons un objet de type Stagiaire dans app.component.ts

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


import { Stagiaire } from './classes/stagiaire';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'cours-angular';
stagiaire: Stagiaire = new Stagiaire(100, 'Wick', 'John');
constructor() {
}
}

9 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular

Affichons l’objet stagiaire dans app.component.html


<ul>
<li> Nom : {{ stagiaire.nom }} </li>
<li> Prénom : {{ stagiaire.prenom }} </li>
</ul>

10 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular
L’écriture suivante
{{ stagiaire }}

H & H: Research and Training 11 / 102


Liaison template/classe (composant) Interpolation {{ ... }}

Angular
L’écriture suivante
{{ stagiaire }}

affiche
[object Object]

11 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular
L’écriture suivante
{{ stagiaire }}

affiche
[object Object]

On peut utiliser un pipe pour affiche un objet au format JSON


{{ stagiaire | json }}

H & H: Research and Training 11 / 102


Liaison template/classe (composant) Interpolation {{ ... }}

Angular
L’écriture suivante
{{ stagiaire }}

affiche
[object Object]

On peut utiliser un pipe pour affiche un objet au format JSON


{{ stagiaire | json }}

Le résultat est
{ "_num": 100, "_nom": "Wick", "_prenom": "John" }

H & H: Research and Training 11 / 102


Liaison template/classe (composant) Interpolation {{ ... }}

Angular

Modifions l’objet stagiaire dans app.component.ts

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


import { Stagiaire } from './classes/stagiaire';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'cours-angular';
stagiaire: Stagiaire = new Stagiaire(100, 'Wick');
constructor() {
}
}

12 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular

Dans app.component.html, et depuis Angular 12, on peut utiliser La coalescence nulle

<ul>
<li> Nom : {{ stagiaire.nom }} </li>
<li> Prénom : {{ stagiaire.prenom ?? "prénom indéfini" }} </li>
</ul>

H & H: Research and Training 13 / 102


Liaison template/classe (composant) Interpolation {{ ... }}

Angular

Créer un tableau d’entiers tab dans app.component.ts

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {

title = 'cours-angular';
stagiaire: Stagiaire = new Stagiaire(100, 'Wick', 'John');
tab: number[] = [2, 3, 5, 8];

constructor() {
}
}

H & H: Research and Training 14 / 102


Liaison template/classe (composant) Interpolation {{ ... }}

Afficher le tableau tab dans app.component.html

<ul>
<li> {{ tab[0] }} </li>
<li> {{ tab['1'] }} </li>
<li> {{ tab["2"] }} </li>
<li> {{ tab[3] }} </li>
</ul>

15 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Afficher le tableau tab dans app.component.html

<ul>
<li> {{ tab[0] }} </li>
<li> {{ tab['1'] }} </li>
<li> {{ tab["2"] }} </li>
<li> {{ tab[3] }} </li>
</ul>

Remarques

Ce code est trop répétitif

Et si on ne connaissait pas le nombre d’éléments

Ou si on ne voulait pas afficher tous les éléments

H & H: Research and Training 15 / 102


Liaison template/classe (composant) Interpolation {{ ... }}

Afficher le tableau tab dans app.component.html

<ul>
<li> {{ tab[0] }} </li>
<li> {{ tab['1'] }} </li>
<li> {{ tab["2"] }} </li>
<li> {{ tab[3] }} </li>
</ul>

Remarques

Ce code est trop répétitif

Et si on ne connaissait pas le nombre d’éléments

Ou si on ne voulait pas afficher tous les éléments

Solution

utiliser les directives (section suivante)

15 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular
Ajouter une méthode direBonjour() dans app.component.ts

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


import { Stagiaire } from './classes/stagiaire';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'cours-angular';
stagiaire: Stagiaire = new Stagiaire(100, 'Wick', 'John');
tab: number[] = [2, 3, 5, 8];
constructor() {
}
direBonjour(): string {
return 'bonjour Angular';
}
}

16 / 102
Liaison template/classe (composant) Interpolation {{ ... }}

Angular

Appeler la méthode direBonjour() dans app.component.html


<p> {{ direBonjour() }} </p>

17 / 102
Liaison template/classe (composant) Property binding [ ... ]

Angular
Pour afficher le contenu de l’attribut title dans le template, on peut utiliser
l’interpolation

<p> {{ title }} </p>

18 / 102
Liaison template/classe (composant) Property binding [ ... ]

Angular
Pour afficher le contenu de l’attribut title dans le template, on peut utiliser
l’interpolation

<p> {{ title }} </p>

On peut aussi utiliser le Property binding sur la propriété JavaScript


textContent

<p [textContent]=title></p>

18 / 102
Liaison template/classe (composant) Property binding [ ... ]

Angular
Pour afficher le contenu de l’attribut title dans le template, on peut utiliser
l’interpolation

<p> {{ title }} </p>

On peut aussi utiliser le Property binding sur la propriété JavaScript


textContent

<p [textContent]=title></p>

[ property binding ]
[property] = ’value’ : permet de remplacer value par sa valeur dans la
classe app.component.ts

18 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular

Évènement (Event)

Action appliquée par l’utilisateur ou simulée par le développeur sur un


.component.html.

Évènement déclenché ⇒ Méthode, dans le .component.ts associé,


exécutée.

19 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular

Évènement (Event)

Action appliquée par l’utilisateur ou simulée par le développeur sur un


.component.html.

Évènement déclenché ⇒ Méthode, dans le .component.ts associé,


exécutée.

Event binding ( ... )

Objectif : associer un évènement à une méthode de la classe associée au


template.

Pas besoin de préfixer l’évènement par ’on’ comme en JavaScript.

19 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular
Ajoutons la méthode alertBonjour() dans app.component.ts

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


import { Stagiaire } from './classes/stagiaire';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {

title = 'cours-angular';
stagiaire: Stagiaire = new Stagiaire(100, 'Wick', 'John');
tab: number[] = [2, 3, 5, 8];

constructor() {
}

alertBonjour(): void {
console.log('bonjour Angular');
}
}

20 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular

Pour exécuter la méthode direBonjour() lorsqu’on clique sur un bouton

<button (click)="alertBonjour()">Dire Bonjour</button>

21 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular

Exercice

Créer deux boutons HTML dont l’un est initialement désactivé (disabled).

À chaque clic sur le bouton activé, celui-ci se désactive tandis que l’autre s’active.

22 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular

Solution

<button [disabled]="disabled" (click)="switchDisabled()">


bouton 1
</button>

<button [disabled]="!disabled" (click)="switchDisabled()">


bouton 2
</button>

23 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular

Solution

<button [disabled]="disabled" (click)="switchDisabled()">


bouton 1
</button>

<button [disabled]="!disabled" (click)="switchDisabled()">


bouton 2
</button>

Sans oublier de déclarer disabled dans data

disabled = true

23 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular
Considérons la zone de saisie suivante dans laquelle nous ne voudrions
accepter que des lettres en minuscule

<div>
<label for="texte"> Merci de bien saisir un texte :
</label>
<input type="text" id="texte" (input)="showValue($event)">
</div>

24 / 102
Liaison template/classe (composant) Event binding ( ... )

Angular
Considérons la zone de saisie suivante dans laquelle nous ne voudrions
accepter que des lettres en minuscule

<div>
<label for="texte"> Merci de bien saisir un texte :
</label>
<input type="text" id="texte" (input)="showValue($event)">
</div>

Pour connaı̂tre le caractère saisi, utilisons l’objet event dans showValue()

showValue(event: Event) {
console.log((event.target as HTMLInputElement).value);
// affiche tous les caractères saisis

console.log((event as InputEvent).data);
// affiche le dernier caractère saisi
}

24 / 102
Directives Angular

Angular
Plusieurs directives possibles

*ngFor

*ngIf

*ngSwitch

ngStyle

ngClass

25 / 102
Directives Angular

Angular
Plusieurs directives possibles

*ngFor

*ngIf

*ngSwitch

ngStyle

ngClass

Ces directives s’utilisent conjointement avec les composants web suivant

ng-container

ng-template

25 / 102
Directives Angular *ngFor

Angular

*ngFor
permet de répéter un traitement (affichage d’un élément HTML)
s’utilise comme un attribut de balise et sa valeur est une
instruction itérative TypeScript

26 / 102
Directives Angular *ngFor

Angular
Afficher les éléments du tableau tab en utilisant *ngFor

<ul>
<li *ngFor="let elt of tab">
{{ elt }}
</li>
</ul>

27 / 102
Directives Angular *ngFor

Angular
Afficher les éléments du tableau tab en utilisant *ngFor

<ul>
<li *ngFor="let elt of tab">
{{ elt }}
</li>
</ul>

Le code précédent est une forme simplifiée du code suivant

<ul>
<ng-template ngFor let-elt [ngForOf]="tab">
<li>{{ elt }} </li>
</ng-template>
</ul>

27 / 102
Directives Angular *ngFor

Angular
Afficher les éléments du tableau tab en utilisant *ngFor

<ul>
<li *ngFor="let elt of tab">
{{ elt }}
</li>
</ul>

Le code précédent est une forme simplifiée du code suivant

<ul>
<ng-template ngFor let-elt [ngForOf]="tab">
<li>{{ elt }} </li>
</ng-template>
</ul>

ng-template n’apparaı̂tra pas dans le DOM.

27 / 102
Directives Angular *ngFor

Et pour avoir l’indice de l’itération courante

<ul>
<li *ngFor="let elt of tab; let i = index">
{{ i }} : {{ elt }}
</li>
</ul>

28 / 102
Directives Angular *ngFor

Et pour avoir l’indice de l’itération courante

<ul>
<li *ngFor="let elt of tab; let i = index">
{{ i }} : {{ elt }}
</li>
</ul>

ou

<ul>
<li *ngFor="let elt of tab; index as i">
{{ i }} : {{ elt }}
</li>
</ul>

28 / 102
Directives Angular *ngFor

Et pour avoir l’indice de l’itération courante

<ul>
<li *ngFor="let elt of tab; let i = index">
{{ i }} : {{ elt }}
</li>
</ul>

ou

<ul>
<li *ngFor="let elt of tab; index as i">
{{ i }} : {{ elt }}
</li>
</ul>

Ou la version la plus longue

<ul>
<ng-template ngFor let-i="index" let-elt [ngForOf]="tab">
<li> {{ i }} : {{ elt }} </li>
</ng-template>
</ul>

28 / 102
Directives Angular *ngFor

Angular

On peut aussi utiliser first pour savoir si l’élément courant est le premier de la liste

<ul>
<li *ngFor="let elt of tab; let i = index; let isFirst = first">
{{ i }} : {{ elt }} : {{ isFirst }}
</li>
</ul>

29 / 102
Directives Angular *ngFor

Angular

On peut aussi utiliser first pour savoir si l’élément courant est le premier de la liste

<ul>
<li *ngFor="let elt of tab; let i = index; let isFirst = first">
{{ i }} : {{ elt }} : {{ isFirst }}
</li>
</ul>

Autres paramètres possible

last : retourne true si l’élément courant est le dernier de la liste, false sinon.

even : retourne true si l’indice de l’élément courant est pair, false sinon.

odd : retourne true si l’indice de l’élément courant est impair, false sinon.

29 / 102
Directives Angular *ngFor

Angular

Considérons la liste suivante (à déclarer dans app.component.ts)


stagiaires: Array<Stagiaire> = [
new Stagiaire(100, 'Wick', 'John'),
new Stagiaire(101, 'Abruzzi', 'John'),
new Stagiaire(102, 'Marley', 'Bob'),
new Stagiaire(103, 'Segal', 'Steven')
];

30 / 102
Directives Angular *ngFor

Angular

Considérons la liste suivante (à déclarer dans app.component.ts)


stagiaires: Array<Stagiaire> = [
new Stagiaire(100, 'Wick', 'John'),
new Stagiaire(101, 'Abruzzi', 'John'),
new Stagiaire(102, 'Marley', 'Bob'),
new Stagiaire(103, 'Segal', 'Steven')
];

Exercice

Écrire un script Angular qui permet d’afficher dans une liste HTML les nom
et prénom de chaque stagiaire de la liste stagiaires.

30 / 102
Directives Angular *ngFor

Angular

Solution
<ul>
<li *ngFor="let st of stagiaires">
{{ st.prenom }} : {{ st.nom }}
</li>
</ul>

31 / 102
Directives Angular *ngFor

Angular
Considérons la méthode suivante (à déclarer dans app.component.ts)

ajouterStagiaires() {
this.stagiaires = [
new Stagiaire(100, 'Wick', 'John'),
new Stagiaire(101, 'Abruzzi', 'John'),
new Stagiaire(102, 'Marley', 'Bob'),
new Stagiaire(103, 'Segal', 'Steven'),
new Stagiaire(104, 'Dalton', 'Jack'),
new Stagiaire(105, 'Maggio', 'Carol')
];
}

32 / 102
Directives Angular *ngFor

Angular
Considérons la méthode suivante (à déclarer dans app.component.ts)

ajouterStagiaires() {
this.stagiaires = [
new Stagiaire(100, 'Wick', 'John'),
new Stagiaire(101, 'Abruzzi', 'John'),
new Stagiaire(102, 'Marley', 'Bob'),
new Stagiaire(103, 'Segal', 'Steven'),
new Stagiaire(104, 'Dalton', 'Jack'),
new Stagiaire(105, 'Maggio', 'Carol')
];
}

Et le bouton suivant permettant de mettre à jour la liste de stagiaires

<ul>
<li *ngFor="let st of stagiaires">
{{ st.prenom }} : {{ st.nom }}
</li>
</ul>
<button (click)="ajouterStagiaires()">Actualiser</button>

32 / 102
Directives Angular *ngFor

Angular
En cliquant sur le bouton, la liste (et la partie du DOM associée)
sera entièrement reconstruite

33 / 102
Directives Angular *ngFor

Angular

Question

Comment faire pour ajouter seulement les éléments manquants sans


reconstruire toute la liste ?

34 / 102
Directives Angular *ngFor

Angular

Question

Comment faire pour ajouter seulement les éléments manquants sans


reconstruire toute la liste ?

Réponse

Utiliser trackBy dans *ngFor qui permet de suivre les éléments lorsqu’ils
sont ajoutés ou supprimés du tableau pour des meilleures performances.

34 / 102
Directives Angular *ngFor

Angular

Nous devons définir une méthode trackBy qui identifie chaque élément de manière
unique

trackByStagiaireNum(index: number, stagiaire: Stagiaire) {


return stagiaire.num;
}

35 / 102
Directives Angular *ngFor

Angular

Nous devons définir une méthode trackBy qui identifie chaque élément de manière
unique

trackByStagiaireNum(index: number, stagiaire: Stagiaire) {


return stagiaire.num;
}

Associons cette méthode à la directive *ngFor

<ul>
<li *ngFor="let st of stagiaires; trackBy:trackByStagiaireNum">
{{ st.prenom }} : {{ st.nom }}
</li>
</ul>
<button (click)="ajouterStagiaires()">Actualiser</button>

35 / 102
Directives Angular *ngFor

Angular
En cliquant sur le bouton, les deux derniers éléments ont été
ajoutés au DOM sans reconstruire intégralement la liste

H I ©
UEL
O
f E LM
ch r e
©A

36 / 102
Directives Angular *ngFor

Angular

Ou la version la plus longue

<ul>
<ng-template ngFor let-st [ngForOf]="stagiaires" [ngForTrackBy]="
trackByStagiaireNum">
<li>
{{ st.prenom }} : {{ st.nom }}
</li>
</ng-template>
</ul>
<button (click)="ajouterStagiaires()">Actualiser</button>

37 / 102
Directives Angular *ngFor

Angular

Remarques

*ngFor nous permet d’itérer sur les tableaux, mais pas sur les
objets.
Il est possible d’itérer sur les objets en utilisant le pipe keyvalue.

38 / 102
Directives Angular *ngIf

Angular
Pour tester puis afficher si le deuxième élément du tableau est impair
<ul>
<li *ngIf="tab[1] % 2 != 0">
{{ tab[1] }} est impair
</li>
</ul>

39 / 102
Directives Angular *ngIf

Angular
Pour tester puis afficher si le deuxième élément du tableau est impair
<ul>
<li *ngIf="tab[1] % 2 != 0">
{{ tab[1] }} est impair
</li>
</ul>

Ou en plus long
<ul>
<ng-template [ngIf]="tab[1] % 2 != 0">
<li>
{{ tab[1] }} est impair
</li>
</ng-template>
</ul>

39 / 102
Directives Angular *ngIf

Angular

Exercice
Utiliser les directives Angular pour afficher le premier élément du
tableau (tab) ainsi que sa parité (pair ou impair).

40 / 102
Directives Angular *ngIf

Une première solution avec *ngIf et else

<ul>
<li *ngIf="tab[0] % 2 != 0; else pair">
{{ tab[0] }} est impair
</li>
<ng-template #pair>
<li>
{{ tab[0] }} est pair
</li>
</ng-template>
</ul>

41 / 102
Directives Angular *ngIf

Une première solution avec *ngIf et else

<ul>
<li *ngIf="tab[0] % 2 != 0; else pair">
{{ tab[0] }} est impair
</li>
<ng-template #pair>
<li>
{{ tab[0] }} est pair
</li>
</ng-template>
</ul>

Ou en plus long

<ul>
<ng-template [ngIf]="tab[0] % 2 != 0" [ngIfElse]=pair>
<li>
{{ tab[0] }} est impair
</li>
</ng-template>
<ng-template #pair>
<li>
{{ tab[0] }} est pair
</li>
</ng-template>
</ul>

41 / 102
Directives Angular *ngIf
Une deuxième solution avec *ngIf, then et else

<ul>
<li *ngIf="tab[0] % 2 != 0; then impair else pair">
Ce code ne sera jamais pris en compte
</li>
<ng-template #impair>
<li>
{{ tab[0] }} est impair
</li>
</ng-template>
<ng-template #pair>
<li>
{{ tab[0] }} est pair
</li>
</ng-template>
</ul>

42 / 102
Directives Angular *ngIf
Une deuxième solution avec *ngIf, then et else

<ul>
<li *ngIf="tab[0] % 2 != 0; then impair else pair">
Ce code ne sera jamais pris en compte
</li>
<ng-template #impair>
<li>
{{ tab[0] }} est impair
</li>
</ng-template>
<ng-template #pair>
<li>
{{ tab[0] }} est pair
</li>
</ng-template>
</ul>

Ou en plus long

<ul>
<ng-template [ngIf]="tab[0] % 2 != 0" [ngIfThen]=impair [ngIfElse]=pair></ng-template>
<ng-template #impair>
<li>
{{ tab[0] }} est impair
</li>
</ng-template>
<ng-template #pair>
<li>
{{ tab[0] }} est pair
</li>
</ng-template>
</ul>

42 / 102
Directives Angular *ngIf

Angular

Remarque

*ngIf et *ngFor ne doivent pas être utilisées dans la même balise.

43 / 102
Directives Angular *ngIf

Angular

Exercice
Utiliser les directives Angular pour afficher sous forme d’une liste
HTML tous les éléments du tableau précédent (tab) ainsi que leur
parité.

44 / 102
Directives Angular *ngIf

Angular
Solution
<ul>
<ng-container *ngFor="let elt of tab">
<li *ngIf="elt % 2 != 0; else sinon">
{{ elt }} est impair
H I ©
EL
</li>
<ng-template #sinon>
O U
LM
<li>

r e f E
{{ elt }} est pair

ch
</li>

©A
</ng-template>
</ng-container>
</ul>

45 / 102
Directives Angular *ngIf

Angular
Solution
<ul>
<ng-container *ngFor="let elt of tab">
<li *ngIf="elt % 2 != 0; else sinon">
{{ elt }} est impair
</li>
<ng-template #sinon>
<li>
{{ elt }} est pair
</li>
</ng-template>
</ng-container>
</ul>

ng-container n’apparaı̂t pas dans le DOM.

45 / 102
Directives Angular *ngIf

Angular

Exercice
Utiliser les directives Angular pour afficher sous forme d’une liste
H
HTML les éléments du tableau moyennes: number[] = [18, 5,I ©
11, 15] avec le message suivant :
UEL
L MO
Si 0 ≤ valeur < 10 alors échec,
e f Emoyen,
13ralors
Si 10 ≤ valeur < h
Si 13 ≤©
Ac
valeur < 16 alors bien,
Sinon très bien.

46 / 102
Directives Angular *ngIf

Angular
Une solution possible

<ul>
<ng-container *ngFor="let elt of moyennes">
<li *ngIf="elt >= 0 && elt < 10; else moyen">
{{ elt }} : échec
</li>
<ng-template #moyen>
<li *ngIf="elt < 13; else bien">
{{ elt }} : moyen
H I ©
EL
</li>
</ng-template>
<ng-template #bien>
O U
LM
<li *ngIf="elt < 16; else tbien">
{{ elt }} : bien
</li>
</ng-template>
r e f E
<ng-template #tbien>
ch
©A
<li *ngIf="elt >= 16; else autre">
{{ elt }} : très bien
</li>
</ng-template>
<ng-template #autre>
<li>
autre
</li>
</ng-template>
</ng-container>
</ul>

47 / 102
Directives Angular *ngIf

Angular

*ngIf vs hidden
*ngIf commentera le contenu si la condition est fausse.
L’élément ne sera pas attaché au DOM.
[hidden] attachera l’élément au DOM et le marquera avec
l’attribut hidden.

48 / 102
Directives Angular ngSwitch

Angular

ngSwitch

Équivalent à switch en JavaScript.


Acceptant des valeurs de type number, string et boolean.

49 / 102
Directives Angular ngSwitch

Exemple avec ngSwitch

<ul>
<ng-container *ngFor="let elt of tab">
<ng-container [ngSwitch]="elt">
<li *ngSwitchCase="1">
{{ elt }} = un
</li>
<li *ngSwitchCase="2">
{{ elt }} = deux
H I ©
</li>
<li *ngSwitchCase="3">
UEL
O
LM
{{ elt }} = trois
</li>

e f
<li *ngSwitchDefault>
r E
ch
{{ elt }} : autre

©A
</li>
</ng-container>
</ng-container>
</ul>

50 / 102
Directives Angular ngSwitch

Exemple avec ngSwitch

<ul>
<ng-container *ngFor="let elt of tab">
<ng-container [ngSwitch]="elt">
<li *ngSwitchCase="1">
{{ elt }} = un
</li>
<li *ngSwitchCase="2">
{{ elt }} = deux
</li>
<li *ngSwitchCase="3">
{{ elt }} = trois
</li>
<li *ngSwitchDefault>
{{ elt }} : autre
</li>
</ng-container>
</ng-container>
</ul>

Pour comparer avec une chaı̂ne de caractère, il faut ajouter les simples quotes (par exemple :
*ngSwitchCase="’bonjour’".

50 / 102
Directives Angular ngSwitch

Angular

Refaire cet exercice avec ngSwitch


Utiliser les directives Angular pour afficher sous forme d’une liste les
éléments du tableau moyennes = [18, 5, 11, 15] avec le
message suivant :
Si 0 ≤ valeur < 10 alors échec
Si 10 ≤ valeur < 13 alors moyen
Si 13 ≤ valeur < 16 alors bien
Sinon très bien

51 / 102
Directives Angular ngSwitch

Angular
Solution

<ul>
<ng-container *ngFor="let elt of tab">
<ng-container [ngSwitch]="true">
<li *ngSwitchCase="elt >= 0 && elt < 10">
{{ elt }} : échec
</li>
<li *ngSwitchCase="elt >= 10 && elt < 13">
{{ elt }} : moyen
</li>
<li *ngSwitchCase="elt >= 13 && elt < 16">
{{ elt }} : bien
</li>
<li *ngSwitchCase="elt >= 16">
{{ elt }} : très bien
</li>
<li *ngSwitchDefault>
autre
</li>
</ng-container>
</ng-container>
</ul>

52 / 102
Directives Angular ngSwitch

Contrairement au *ngIf, plusieurs *ngSwitchCase peuvent être exécutée pour une


même valeur. Par conséquence, le code suivant ne réalise pas le travail demandé

<ul>
<ng-container *ngFor="let elt of moyennes">
<ng-container [ngSwitch]="true">
<li *ngSwitchCase="elt >= 0 && elt < 10">
{{ elt }} : échec
</li>
<li *ngSwitchCase="elt < 13">
{{ elt }} : moyen
</li>
<li *ngSwitchCase="elt < 16">
{{ elt }} : bien
</li>
<li *ngSwitchCase="elt >= 16">
{{ elt }} : très bien
</li>
<li *ngSwitchDefault>
autre
</li>
</ng-container>
</ng-container>
</ul>

53 / 102
Directives Angular ngSwitch

Angular

Remarques

L’objectif de l’exercice précédent était une excellente occasion de se familiariser


avec les directives Angular telles que *ngSwitchCase et *ngIf.

Ceci est essentiel pour comprendre et maı̂triser la création d’interfaces


utilisateur dynamiques dans Angular.

Quand c’est possible, on préfère déplacer la logique de calcul dans les fichiers
TypeScript (*.component.ts).

Cela réduit considérablement la complexité du HTML et rend le code plus lisible


et plus facile à maintenir.

54 / 102
Directives Angular ngPlural

Angular

ngPlural
Introduit dans Angular 10. H I ©
UEL
O
Similaire à ngSwitch mais n’acceptant que des valeurs
numériques.
f E LM
r e
h le cas par défaut, mais on peut utiliser la
Pas de mot-clécpour
©
constante A
other.

55 / 102
Directives Angular ngPlural

Angular
Exemple avec ngPlural

<ul>
<ng-container *ngFor="let elt of tab">
<li>
<ng-container [ngPlural]="elt">
<ng-template ngPluralCase="1">
{{ elt }} : un
</ng-template>
<ng-template ngPluralCase="2">
{{ elt }} : deux
</ng-template>
<ng-template ngPluralCase="3">
{{ elt }} : trois
</ng-template>
<ng-template ngPluralCase="other">
{{ elt }} : autre
</ng-template>
</ng-container>
</li>
</ng-container>
</ul>

56 / 102
Directives Angular ngStyle

Angular

ngStyle

permet de modifier dynamiquement le style d’un élément HTML.

permet de récupérer des valeurs définies dans la partie script ou style.

57 / 102
Directives Angular ngStyle

Angular

ngStyle

permet de modifier dynamiquement le style d’un élément HTML.

permet de récupérer des valeurs définies dans la partie script ou style.

Remarque

N’utilisez jamais ngStyle dans une balise <ng-template> ou <ng-container>


car ces dernières ne sont pas directement présentes dans le DOM.

57 / 102
Directives Angular ngStyle

Angular

Ajoutons les deux attributs suivants dans app.component.ts

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

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {

// le contenu précédent

couleur = 'white';
couleurBg = 'red';
}

58 / 102
Directives Angular ngStyle

Angular
Pour attribuer une valeur à la propriété CSS d’une balise

<p [style.background-color]='couleurBg'>
{{ title }}
</p>

59 / 102
Directives Angular ngStyle

Angular
Pour attribuer une valeur à la propriété CSS d’une balise

<p [style.background-color]='couleurBg'>
{{ title }}
</p>

Pour deux propriétés

<p [style.background-color]='couleurBg' [style.color]='couleur'>


{{ title }}
</p>

59 / 102
Directives Angular ngStyle

Angular
Pour attribuer une valeur à la propriété CSS d’une balise

<p [style.background-color]='couleurBg'>
{{ title }}
</p>

Pour deux propriétés

<p [style.background-color]='couleurBg' [style.color]='couleur'>


{{ title }}
</p>

Remarque

L’écriture précédente peut-être simplifiée en utilisant la directive ngStyle.

59 / 102
Directives Angular ngStyle

Angular

ngStyle
permet de modifier le style d’un élément HTML.
s’utilise conjointement avec le property binding pour récupérer
des valeurs définies dans la classe.

60 / 102
Directives Angular ngStyle

Angular

Simplification avec ngStyle

<p [ngStyle]="{ color: couleur, backgroundColor: couleurBg }">


{{ title }}
</p>

61 / 102
Directives Angular ngStyle

Angular

ngStyle peut aussi prendre comme valeur un objet

<p [ngStyle]="monStyle">
{{ title }}
</p>

62 / 102
Directives Angular ngStyle

Angular

ngStyle peut aussi prendre comme valeur un objet

<p [ngStyle]="monStyle">
{{ title }}
</p>

Contenu de monStyle dans .component.ts

monStyle = { color: 'white', backgroundColor: 'skyblue' }

62 / 102
Directives Angular ngStyle

Angular
Il est possible de définir des méthodes dans app.component.ts qui gèrent le
style d’un élément HTML
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// le contenu précédent

getColor(): string {
return 'white';
}
getBgColor(): string {
return 'red';
}
}

63 / 102
Directives Angular ngStyle

Angular

Pour afficher le contenu de l’attribut nom dans le template avec une couleur de
fond rouge

<p [ngStyle]="{ color: getColor(), bgColor: getBgColor() }">


{{ title }}
</p>

64 / 102
Directives Angular ngClass

Angular

ngClass

permet d’attribuer de nouvelles classes d’un élément HTML.

s’utilise conjointement avec le property binding pour récupérer des valeurs


définies dans la classe ou dans la feuille de style.

65 / 102
Directives Angular ngClass

Angular

ngClass

permet d’attribuer de nouvelles classes d’un élément HTML.

s’utilise conjointement avec le property binding pour récupérer des valeurs


définies dans la classe ou dans la feuille de style.

Remarque

N’utilisez jamais ngClass dans une balise <ng-template> ou <ng-container>


car ces dernières ne sont pas directement présentes dans le DOM.

65 / 102
Directives Angular ngClass

Considérons le contenu suivant de app.component.ts


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

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// le contenu précédent
}

66 / 102
Directives Angular ngClass

Considérons le contenu suivant de app.component.ts


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

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// le contenu précédent
}

On définit deux classes rouge et bleu dans app.component.css


.rouge {
color: red;
}
.bleu {
color: blue;
}
.gras {
font-weight: bold;
}

66 / 102
Directives Angular ngClass

Angular
Pour associer la classe rouge à la balise <p>
<p [ngClass]="{ 'rouge': true }">
{{ title }}
</p>

67 / 102
Directives Angular ngClass

Angular
Pour associer la classe rouge à la balise <p>
<p [ngClass]="{ 'rouge': true }">
{{ title }}
</p>

On peut aussi appeler une méthode dans la directive ngClass


<p [ngClass]="{ 'rouge': afficherEnRouge() }">
{{ title }}
</p>

67 / 102
Directives Angular ngClass

Angular
Pour associer la classe rouge à la balise <p>
<p [ngClass]="{ 'rouge': true }">
{{ title }}
</p>

On peut aussi appeler une méthode dans la directive ngClass


<p [ngClass]="{ 'rouge': afficherEnRouge() }">
{{ title }}
</p>

Définissons la méthode afficherEnRouge dans app.component.ts


afficherEnRouge(): boolean {
return this.couleur === 'blue' ? true : false;
}

67 / 102
Directives Angular ngClass

Angular
Ainsi, on peut faire aussi un affichage conditionnel

<p [ngClass]=" {'rouge': nom == 'wick' }">


{{ title }}
</p>

68 / 102
Directives Angular ngClass

Angular
Ainsi, on peut faire aussi un affichage conditionnel

<p [ngClass]=" {'rouge': nom == 'wick' }">


{{ title }}
</p>

Ou encore (le paragraphe sera affiché en rouge si nom contient wick, en bleu sinon)

<p [ngClass]="{ 'rouge': title == 'ng', 'bleu': title != 'ng' }">


{{ title }}
</p>

68 / 102
Directives Angular ngClass

Angular
Ainsi, on peut faire aussi un affichage conditionnel

<p [ngClass]=" {'rouge': nom == 'wick' }">


{{ title }}
</p>

Ou encore (le paragraphe sera affiché en rouge si nom contient wick, en bleu sinon)

<p [ngClass]="{ 'rouge': title == 'ng', 'bleu': title != 'ng' }">


{{ title }}
</p>

Plusieurs classes peuvent être associées à un même élément

<p [ngClass]="{ 'rouge': title == 'ng', 'bleu': title != 'ng', 'gras':


title.length!= 2 }">
{{ title }}
</p>

68 / 102
Directives Angular ngClass

Angular

On peut aussi utiliser les expressions ternaires


<p [ngClass]="nom == 'wick' ? 'rouge' : 'bleu'">
{{ title }}
</p>

69 / 102
Directives Angular ngClass

Angular

Exercice
Utiliser ngClass pour afficher en bleu les éléments pairs du tableau
précédent (tab) et en rouge les éléments impairs.

70 / 102
Directives Angular ngClass

Angular
Première solution

<ul>
<ng-container *ngFor="let elt of tab">
<li [ngClass]="{'rouge': elt % 2 != 0, 'bleu': elt % 2 == 0}">
{{ elt }}
</li>
</ng-container>
</ul>

71 / 102
Directives Angular ngClass

Angular
Première solution

<ul>
<ng-container *ngFor="let elt of tab">
<li [ngClass]="{'rouge': elt % 2 != 0, 'bleu': elt % 2 == 0}">
{{ elt }}
</li>
</ng-container>
</ul>

Deuxième solution

<ul>
<ng-container *ngFor="let elt of tab">
<li [ngClass]="elt % 2 == 0 ? 'bleu' : 'rouge'">
{{ elt }}
</li>
</ng-container>
</ul>

71 / 102
Directives Angular ngClass

Angular
Troisième solution
<ul>
<ng-container *ngFor="let elt of tab">
<li [ngClass]="{'rouge': !estPair(elt), 'bleu':
estPair(elt)}">
{{ elt }}
</li>
</ng-container>
</ul>

72 / 102
Directives Angular ngClass

Angular
Troisième solution
<ul>
<ng-container *ngFor="let elt of tab">
<li [ngClass]="{'rouge': !estPair(elt), 'bleu':
estPair(elt)}">
{{ elt }}
</li>
</ng-container>
</ul>

Dans app.component.ts, on définit la méthode estPair


estPair(elt: number): boolean {
return elt % 2 === 0;
}

72 / 102
Directives Angular ngClass

Angular
Considérons la liste stagiaires précédente
stagiaires: Array<Stagiaire> = [
new Stagiaire(100, 'Wick', 'John'),
new Stagiaire(101, 'Abruzzi', 'John'),
new Stagiaire(102, 'Marley', 'Bob'),
new Stagiaire(103, 'Segal', 'Steven')
];

73 / 102
Directives Angular ngClass

Angular
Considérons la liste stagiaires précédente
stagiaires: Array<Stagiaire> = [
new Stagiaire(100, 'Wick', 'John'),
new Stagiaire(101, 'Abruzzi', 'John'),
new Stagiaire(102, 'Marley', 'Bob'),
new Stagiaire(103, 'Segal', 'Steven')
];

Exercice

Écrire un script Angular qui permet d’afficher dans une liste HTML les
éléments du tableau stagiaires (afficher uniquement nom et prénom). Les
éléments d’indice pair seront affichés en rouge, les impairs en bleu.

73 / 102
Directives Angular ngClass

Angular
Première solution
<ul>
<ng-container *ngFor="let elt of stagiaires; let isEven =
even; let isOdd = odd">
<li [ngClass]="{'rouge': isEven,'bleu': isOdd}">
{{ elt.nom }} {{ elt.prenom }}
</li>
</ng-container>
</ul>

H & H: Research and Training 74 / 102


Directives Angular ngClass

Angular
Première solution
<ul>
<ng-container *ngFor="let elt of stagiaires; let isEven =
even; let isOdd = odd">
<li [ngClass]="{'rouge': isEven,'bleu': isOdd}">
{{ elt.nom }} {{ elt.prenom }}
</li>
</ng-container>
</ul>

Deuxième solution
<ul>
<ng-container *ngFor="let elt of stagiaires; let i = index;">
<li [ngClass]="i % 2 != 0 ? 'rouge' : 'bleu'">
{{ elt.nom + " " + elt.prenom }}
</li>
</ng-container>
</ul>

H & H: Research and Training 74 / 102


Directives Angular ngClass

Angular
Troisième solution

<ul>
<ng-container *ngFor="let stagiaire of stagiaires">
<li [ngStyle]="{color: getNextColor()}">
{{ stagiaire.prenom }} {{ stagiaire. nom }}
</li>
</ng-container>
</ul>

75 / 102
Directives Angular ngClass

Angular
Troisième solution

<ul>
<ng-container *ngFor="let stagiaire of stagiaires">
<li [ngStyle]="{color: getNextColor()}">
{{ stagiaire.prenom }} {{ stagiaire. nom }}
</li>
</ng-container>
</ul>

Dans app.component.ts, on définit la méthode getNextColor

couleur = 'blue';
getNextColor(): string {
this.couleur = this.couleur === 'red' ? 'blue' : 'red';
return this.couleur;
}

75 / 102
Control Flow Syntax

Angular

Control Flow Syntax


Introduit dans Angular 17
Ayant comme objectif de remplacer les directives structurelles
@for pour remplacer *ngFor
@if pour remplacer *ngIf
@switch pour remplacer *ngSwitch

76 / 102
Control Flow Syntax

Angular

Pour essayer Control Flow Syntax dans un projet existant, il faut


utiliser la migration suivante
ng generate @angular/core:control-flow

77 / 102
Control Flow Syntax @for

Angular
Afficher les éléments du tableau tab en utilisant *ngFor

<ul>
@for (elt of tab; track elt) {
<li> {{ elt }} </li>
}
</ul>

78 / 102
Control Flow Syntax @for

Angular
Afficher les éléments du tableau tab en utilisant *ngFor

<ul>
@for (elt of tab; track elt) {
<li> {{ elt }} </li>
}
</ul>

track elt

permet de spécifier la clé utilisée pour associer les éléments du tableau aux
vues dans le DOM.

permet à Angular d’exécuter un ensemble minimal d’opérations sur le DOM


lorsque des éléments sont ajoutés, supprimés ou déplacés dans une collection.

78 / 102
Control Flow Syntax @for

Angular

Et pour avoir l’indice de l’itération courante, on peut utiliser la variable


contextuelle $index

<ul>
@for (elt of tab; track elt) {
<li>{{ $index }} {{ elt }} </li>
}
</ul>

79 / 102
Control Flow Syntax @for

Angular

Et pour avoir l’indice de l’itération courante, on peut utiliser la variable


contextuelle $index

<ul>
@for (elt of tab; track elt) {
<li>{{ $index }} {{ elt }} </li>
}
</ul>

ou

<ul>
@for (elt of tab; let i = $index; track i) {
<li>{{ i }} {{ elt }} </li>
}
</ul>

79 / 102
Control Flow Syntax @for

Angular

Autres variables contextuelles

$first : retourne true si l’élément courant est le premier de la liste, false sinon.

$last : retourne true si l’élément courant est le dernier de la liste, false sinon.

$even : retourne true si l’indice de l’élément courant est pair, false sinon.

$odd : retourne true si l’indice de l’élément courant est impair, false sinon.

$count : retourne le nombre total d’éléments dans la collection.

80 / 102
Control Flow Syntax @for

Angular

Exemple avec $first

<ul>
@for (elt of tab; let i = $index; let premier = $first ;
track i) {
<li>{{ first }} {{ i }} {{ elt }} </li>
}
</ul>

81 / 102
Control Flow Syntax @empty

Angular

Le bloc optionnel @empty est exécuté lorsque la liste est vide


<ul>
@for (elt of tab; track i) {
<li>{{ elt }} </li>
} @empty {
La liste ne contient aucun élément.
}
</ul>

82 / 102
Control Flow Syntax @empty

Angular

Considérons la liste suivante (à déclarer dans app.component.ts)


stagiaires: Array<Stagiaire> = [
new Stagiaire(100, 'Wick', 'John'),
new Stagiaire(101, 'Abruzzi', 'John'),
new Stagiaire(102, 'Marley', 'Bob'),
new Stagiaire(103, 'Segal', 'Steven')
];

H & H: Research and Training 83 / 102


Control Flow Syntax @empty

Angular

Considérons la liste suivante (à déclarer dans app.component.ts)


stagiaires: Array<Stagiaire> = [
new Stagiaire(100, 'Wick', 'John'),
new Stagiaire(101, 'Abruzzi', 'John'),
new Stagiaire(102, 'Marley', 'Bob'),
new Stagiaire(103, 'Segal', 'Steven')
];

Exercice

Écrire un script Angular qui permet d’afficher dans une liste HTML les nom
et prénom de chaque stagiaire de la liste stagiaires.

83 / 102
Control Flow Syntax @empty

Angular

Solution
<ul>
@for (st of stagiaires; track st.num) {
<li> {{ st.prenom }} {{ st.nom }} </li>
}
</ul>

84 / 102
Control Flow Syntax @empty

Angular

Remarques

@for nous permet d’itérer sur les tableaux, mais pas sur les objets.

Il est possible d’itérer sur les objets en utilisant le pipe keyvalue.

85 / 102
Control Flow Syntax @empty

Angular

Exemple d’utilisation de keyvalue dans des boucles imbriquées

<ul>
@for (st of stagiaires; track st.num) {
@for (elt of st | keyvalue ; track elt) {
<li> {{ elt.key }} {{ elt.value }}</li>
}
}
</ul>

86 / 102
Control Flow Syntax @if

Angular

Exemple avec @if


<ul>
<li>
@if(tab[1] % 2 != 0) {
{{ tab[1] }} est impair
}
</li>
</ul>

87 / 102
Control Flow Syntax @else

Angular

Exemple avec @else


<ul>
<li>
@if(tab[1] % 2 != 0) {
{{ tab[1] }} est impair
} @else {
{{ tab[1] }} est pair
}
</li>
</ul>

88 / 102
Control Flow Syntax @else

Angular

Exercice
Utiliser les Control Flow Syntax d’Angular pour afficher sous forme
d’une liste HTML les éléments du tableau moyennes: number[] =
[18, 5, 11, 15] avec le message suivant :
Si 0 ≤ valeur < 10 alors échec,
Si 10 ≤ valeur < 13 alors moyen,
Si 13 ≤ valeur < 16 alors bien,
Sinon très bien.

89 / 102
Control Flow Syntax @switch

Angular
Exemple avec @switch

<ul>
@for(elt of tab; track $index) {
<li>
@switch(elt) {
@case(1) {
{{ elt }} = un
}
@case(2) {
{{ elt }} = deux
}
@case(3) {
{{ elt }} = trois
}
@default {
{{ elt }} = autre
}
}
</li>
}
</ul>

90 / 102
Control Flow Syntax @switch

Angular

Refaire cet exercice avec @switch


Utiliser les directives Angular pour afficher sous forme d’une liste les
éléments du tableau moyennes = [18, 5, 11, 15] avec le
message suivant :
Si 0 ≤ valeur < 10 alors échec
Si 10 ≤ valeur < 13 alors moyen
Si 13 ≤ valeur < 16 alors bien
Sinon très bien

91 / 102
Valeurs réactives

Angular
Créons le composant reactive.component.ts avec le code suivant

export class ReactiveComponent {


value1 = 2
value2 = 5
resultat = 0
constructor() {
setInterval(
() => this.value1 += 10,
5000
)
this.resultat = this.value1 + this.value2
}
}

92 / 102
Valeurs réactives

Angular
Créons le composant reactive.component.ts avec le code suivant

export class ReactiveComponent {


value1 = 2
value2 = 5
resultat = 0
constructor() {
setInterval(
() => this.value1 += 10,
5000
)
this.resultat = this.value1 + this.value2
}
}

Le contenu de reactive.component.html est le suivant

<p>
{{ value1 }} + {{ value2 }} = {{ resultat }}
</p>

H & H: Research and Training 92 / 102


Valeurs réactives

Angular

Question

Que sera le résultat de ce code ?

93 / 102
Valeurs réactives

Angular

Question

Que sera le résultat de ce code ?

Résultat attendu Résultat obtenu

Au chargement de la page 2 + 3 = 5 Au chargement de la page 2 + 3 = 5

5 secondes plus tard, 3 sera remplacé 5 secondes plus tard, 3 est remplacé par
par 13 13

Contenu attendu : 2 + 13 = 15 Contenu affiché : 2 + 13 = 5

93 / 102
Valeurs réactives

Angular
Conclusion

Quand valeur1 ou valeur2 change, resultat ne se met pas à jour.

94 / 102
Valeurs réactives

Angular
Conclusion

Quand valeur1 ou valeur2 change, resultat ne se met pas à jour.

Solution

Utiliser les valeurs réactives (signaux).

94 / 102
Valeurs réactives

Angular
Conclusion

Quand valeur1 ou valeur2 change, resultat ne se met pas à jour.

Solution

Utiliser les valeurs réactives (signaux).

Signal

une enveloppe autour d’une valeur qui peut informer les consommateurs intéressés
lorsque cette valeur change.

peut contenir n’importe quel type de valeur : primitive ou complexe.

94 / 102
Valeurs réactives

Angular

Angular propose deux types de signaux

Writable Signals : valeur modifiable via les méthodes


set(newValue) ou
update(callback)

Computed Signals (en lecture seule) : obtient une valeur à partir


d’un ou plusieurs autres signaux.

95 / 102
Valeurs réactives signal

Angular
Commençons par initialiser value1 et value2 avec la fonction signal

value1 = signal(2)
value2 = signal(5)

96 / 102
Valeurs réactives signal

Angular
Commençons par initialiser value1 et value2 avec la fonction signal

value1 = signal(2)
value2 = signal(5)

Remarque

value1 et value2 sont de type WritableSignal.

96 / 102
Valeurs réactives signal

Angular
Commençons par initialiser value1 et value2 avec la fonction signal

value1 = signal(2)
value2 = signal(5)

Remarque

value1 et value2 sont de type WritableSignal.

On peut donc typer ainsi

value1: WritableSignal<number> = signal(2)


value2: WritableSignal<number> = signal(5)

96 / 102
Valeurs réactives signal

Angular

Préparons l’attribut resultat et initialisons le à 0


resultat: Signal<number> = signal(0)

97 / 102
Valeurs réactives signal

Angular

Préparons l’attribut resultat et initialisons le à 0


resultat: Signal<number> = signal(0)

Remarque
resultat est de type Signal<number> donc il est en lecture-seule.

97 / 102
Valeurs réactives computed

Angular

Dans le constructeur, utilisons update pour modifier value1 et computed pour recalculer
la valeur de resultat après chaque changement de valeur de value1 ou value2

constructor() {
setInterval(
() => this.value1.update(val => val += 10),
2000
)
this.resultat = computed(() => this.value1() + this.value2())
}

98 / 102
Valeurs réactives computed

Angular

Dans le constructeur, utilisons update pour modifier value1 et computed pour recalculer
la valeur de resultat après chaque changement de valeur de value1 ou value2

constructor() {
setInterval(
() => this.value1.update(val => val += 10),
2000
)
this.resultat = computed(() => this.value1() + this.value2())
}

Les imports nécessaires

import { Component, Signal, WritableSignal, computed, signal } from '


@angular/core';

98 / 102
Valeurs réactives computed

Angular

Pour accéder aux valeurs d’un signal, on utilise le getter (on rajoute donc les
parenthèses)

<p>
{{ value1() }} + {{ value2() }} = {{ resultat() }}
</p>

99 / 102
Valeurs réactives effect

Angular

Pour suivre l’état d’un signal, on utilise effect

export class ReactiveComponent {


value1: WritableSignal<number> = signal(2)
value2: WritableSignal<number> = signal(5)
resultat: Signal<number> = signal(0)
constructor() {
setInterval(
() => this.value1.update(val => val += 10),
2000
)
this.resultat = computed(() => this.value1() + this.value2())
}
r = effect(() => console.log('effet', this.value1(), this.resultat()))
}

100 / 102
Valeurs réactives effect

Angular

Pour suivre l’état d’un signal, on utilise effect

export class ReactiveComponent {


value1: WritableSignal<number> = signal(2)
value2: WritableSignal<number> = signal(5)
resultat: Signal<number> = signal(0)
constructor() {
setInterval(
() => this.value1.update(val => val += 10),
2000
)
this.resultat = computed(() => this.value1() + this.value2())
}
r = effect(() => console.log('effet', this.value1(), this.resultat()))
}

Remarque

effect observe resultat et value1. Le changement de valeur de tout autre signal ne permettra pas de le déclencher.

100 / 102
Valeurs réactives effect

Angular

effect peut-être utilisé dans les cas suivants

enregistrer la valeur d’un signal à l’aide d’un framework de journalisation.

exporter la valeur d’un signal vers le Web Storage ou un Cookie.

enregistrer la valeur d’un signal dans la base de données.

101 / 102
Valeurs réactives effect

Angular

Pour appliquer un traitement particulier à la destruction de l’effect

r = effect((onCleanup) => {
console.log('effet', this.value1(), this.resultat())
onCleanup(() => {
console.log("Traitement appliqué à la destruction de l'effect");
});
})

102 / 102

Vous aimerez peut-être aussi