6-5 Directives (@for et @if)
Le composant ProjetsListe
est quelque peu inutile dans sa forme actuelle et ne fait qu'afficher le texte projets-liste works!
.
Et si on essayait d'afficher une liste de projets?
Nous n'avons pas encore intégré le concept de faire des appels d'API, donc nous commencerons en codant en dure une liste de projets dans le composant.
Créer une propriété pour contenir les projets
Dans ProjetsListe
, ajoutez une propriété projets
de type string[]
. Notre liste de projets sera pour l'instant une simple liste de string
.
@Component({
selector: 'app-projets-liste',
imports: [],
template: `
<p>
projets-liste works!
</p>
`,
styles: ``
})
export class ProjetsListe {
protected projets: string[] = [
"Discreddit",
"Organisation du Lan Party",
"Organisation de la soirée jeu vidéo",
]
}
Un composant est une classe! Ainsi, en TypeScript on peut définir une nouvelle propriété et l'initialiser dans la classe.
On crée une propriété en la nommant (ex.: projets
), deux points (:
), suivi du type (un tableau de string ici string[]
).
De plus, on utilise protected
puisque cette propriété est pertinente à la classe elle-même, mais aussi au template HTML, sans toutefois vouloir l'exposer aux autres classes.
Faire de cette propriété un signal? Arf 😕
Pour l'instant, afin de garder les choses simples, nous ne ferons pas du array un signal comme pour la propriété title
du composant App
. C'est que pour des propriétés autre que de simples string
ou number
, la façon de mettre à jour un signal devient un peu plus complexe.
À cette étape-ci, trop complexe pour ce que nous avons besoin de faire!
Angular détectera quand même les changements, c'est seulement que ce sera moins performant. Et pour le niveau de complexité de notre app... ça ne paraitra pas!
Afficher la liste à l'aide d'une boucle (directive @for
)
Mais comment passer d'un tableau dans le composant à afficher la liste dans la portion template
de ce dernier.
Pour ce faire, on peut utiliser les directives.
Angular en propose plusieurs, mais parmi les plus populaires:
@if
pour conditionnellement afficher un élément (équivalent dev-if
en Vue)@for
pour répéter un élément en fonction d'éléments d'une liste (équivalent dev-for
en Vue)@switch
pour afficher un élément parmi plusieurs possibilités en fonction d'une condition de type switch.
Nous aurons l'occasion d'explorer plus en détail certaines de ces directives plus tard, mais pour l'instant @for
semble tout indiqué!
Syntaxe de @for
@for (item of items; track item.name) {
<li>{{ item.name }}</li>
} @empty {
<li>There are no items.</li>
}
La fonction track
dans une boucle @for
permet à Angular d'identifier de manière unique chaque élément de la liste. Elle indique à Angular comment "suivre" les éléments lors des mises à jour du DOM.
Dans le contexte d'un objet, on pourrait utiliser un identifiant unique (par exemple, id
).
Pour une liste simple, on peut utiliser $index
, soit l'index de l'élément dans le tableau.
Esssentiellement, avec track, Angular peut identifier quels éléments ont changé, été ajoutés ou supprimés, et ne met à jour que les parties nécessaires du DOM.
Utiliser @for
pour la liste de projets
-
Créez une liste
ul
vide pour commencersrc/app/projets-liste.ts@Component({
selector: 'app-projets-liste',
imports: [],
template: `
<ul>
</ul>
`,
styles: ``
}) -
Débutez une boucle
@for
src/app/projets-liste.ts@Component({
selector: 'app-projets-liste',
imports: [],
template: `
<ul>
@for (projet of projets) {
}
</ul>
`,
styles: ``
})attentionVous aurez une erreur comme quoi
track
est requis!La fonction
track
dans une boucle@for
permet à Angular d'identifier de manière unique chaque élément de la liste. Elle indique à Angular comment "suivre" les éléments lors des mises à jour du DOM.Dans le contexte d'un objet, on pourrait utiliser un identifiant unique (par exemple,
id
).Pour une liste simple, ce qui est notre cas, on peut utiliser
$index
, soit l'index de l'élément dans le tableau.Esssentiellement, avec track, Angular peut identifier quels éléments ont changé, été ajoutés ou supprimés, et ne met à jour que les parties nécessaires du DOM.
-
Utilisez
$index
avectrack
pour identifier chaque élément par son index dans le tableau.src/app/projets-liste.ts<ul>
@for (projet of projets; track $index) {
}
</ul> -
Finalement, pour chaque itération de la boucle, on voudra afficher un
<li>
pour le projetsrc/app/projets-liste.ts@Component({
selector: 'app-projets-liste',
imports: [],
template: `
<ul>
@for (projet of projets; track $index) {
<li></li>
}
</ul>
`,
styles: ``
}) -
Observez dans votre navigateur le résultat
http://localhost:4200 -
Comme
projet of projets
expose une variableprojet
, il est maintenant possible d'utiliser le principe d'interpolation vue précédemment pour afficher le texte associé au projet!src/app/projets-liste.ts@Component({
selector: 'app-projets-liste',
imports: [],
template: `
<ul>
@for (projet of projets; track $index) {
<li>{{ projet }}</li>
}
</ul>
`,
styles: ``
}) -
Et maintenant dans votre navigateur:
http://localhost:4200
Gérer un tableau vide avec @empty
La directive @for
permet de lui ajouter @empty
pour gérer le cas dans lequel le tableau serait vide. Cela est particulièrement utile pour afficher un message à l'utilisateur.
Par exemple, pour la liste de projets:
- Ajoutez la directive
@empty
à la suite de la boucle@for
src/app/projets-liste.ts<ul>
@for (projet of projets; track $index) {
<li>{{ projet }}</li>
} @empty {
<li>Aucun projet</li>
}
</ul> - Videz votre tableau de projets en mettant les projets en commentaire.
export class ProjetsListe {
protected projets: string[] = [
/*"Discreddit",
"Organisation du Lan Party",
"Organisation de la soirée jeu vidéo",*/
];
} - Regardez le rendu sur la page d'accueil! 😊
Affichage conditionnel avec @if
Nous pouvons aussi gérer l'affichage conditionnel d'éléments à l'aide de la directive @if
. En effet, @empty
est très pratique, mais son désavantage principal est qu'il doit être directement lié à la boucle.
Cela veut dire que dans l'exemple précédent, le message "Aucun projet" doit obligatoirement être affiché dans un li
puisque la boucle for
est à l'intérieur d'un ul
.
<ul>
@for(projet of projets; track $index){
<li>{{ projet }}</li>
} @empty {
<li>Aucun projet</li>
}
</ul>
Il serait possible de plutôt utiliser @if
pour carrément afficher la liste ou non.
@if est une directive de contrôle de flux qui permet d'afficher conditionnellement du contenu dans le template.
@if (condition) {
<div>Contenu affiché si la condition est vraie</div>
}
-
Ajoutez une directive
@if
qui vérifie si la taille du tableau est supérieure à0
pour afficher la liste.@if(projets.length > 0){
<ul>
@for (projet of projets; track $index) {
<li>{{ projet }}</li>
} @empty {
<li>Aucun projet</li>
}
</ul>
} -
Ajoutez une condition
@else
pour gérer le cas où la taille serait0
et donc, le tableau vide.@if(projets.length > 0){
<ul>
@for (projet of projets; track $index) {
<li>{{ projet }}</li>
} @empty {
<li>Aucun projet</li>
}
</ul>
} @else {
<p>Aucun projet</p>
} -
Remarquez le résultat dans votre navigateur!
infoCela est visuellement mieux puisque nous ne voulons pas réellement afficher une liste lorsqu'il n'y a pas de projets, on veut simplement afficher un message.
Réafficher les projets
Parfait, nous sommes en mesure de gérer le cas où la liste est vide!
Pour la suite, assurez-vous d'afficher des projets et donc d'enlever le commentaire dans votre tableau:
export class ProjetsListe {
protected projets: string[] = [
"Discreddit",
"Organisation du Lan Party",
"Organisation de la soirée jeu vidéo",
];
}