Conditions et boucles dans les templates Angular

Article abordant la manière d'utiliser la liaison de données à double sens dans les composants Angular

Chaque composant possède une partie vue que l’on appelle un template.

Comme son nom l’indique, un template est fait pour être dynamique, modulable. C’est un peu un patron que l’on vient personnaliser au besoin grâce à des endroits dynamiques (string interpolation, property binding et toutes les autres notions que j’ai abordé dans mon précédent article que tu peux consulter dès maintenant !)

Cependant, il sera parfois nécessaire de pouvoir agir sur ce template avant, durant ou bien après sa construction.

Ceci va être possible grâce aux directives. Elles ressemblent à des attributs HTML que l’on positionne sur des balises HTML classiques ou bien directement sur des composants Angular.

Il existe 2 types de directives:

  • structurelles (elles vont intervenir avant la génération du template)
  • par attribut (elles vont intervenir après la génération du template)

Les directives structurelles

On utilisera le plus souvent 2 directives structurelles:

  • celle qui permet de créer une condition
  • celle qui permet de créer une boucle

Pour rappel, tout se fera côté HTML sur les balises (classiques ou d’un composant).

Pour ajouter une condition côté HTML, on utilisera la directive *ngIf.

Pour boucler et créer un élément selon un tableau, on utilisera la directive *ngFor.

Voyons maintenant chacune de ces directives en détails.

Utilisation *ngIf

Comme on a pu le voir avec le property binding, il est possible d’interpréter du Javascript entre les «  ». (Ex: [disabled]= »duJsIci »)

Le fonctionnement du *ngIf va être assez similaire, on va lui donner la condition à l’intérieur des «  ».

Reprenons notre projet hello-world.

Nous allons ajouter une condition dans notre composant who-am-i.component.html afin de modifier le nom de l’utilisateur si celui est équal à une certaine valeur.

Exemple, si mon composant reçoit le prénom « Thomas » alors je le renommerais en « Tom ».

Nous allons modifier le fichier who-am-i.component.html:

<div *ngIf="firstName === 'Thomas'">Hey, mon nom est Tom {{lastName}}</div>
<div *ngIf="firstName !== 'Thomas'">Hey, mon nom est {{firstName}} {{lastName}}</div>
<button
  (click)="onClickShowAge()"
  [hidden]="isAgeHidden">Afficher mon âge !</button>

On peut voir ici que la condition se fait sur la variable firstName qui est l’input reçu depuis le parent. Selon sa valeur, je modifierais ou non le champ firstName.

Utilisation du *ngFor

Reprenons maintenant le contenu de notre fichier app.component.html.

On peut voir que l’on crée actuellement 2 utilisateurs de manière totalement statique ce qui est fonctionnel mais pas optimal. Imaginons que l’on ait 20 utilisateurs, on serait obligé de dupliquer le code 20 fois..

Heureusement, côté HTML nous avons l’équivalent de la boucle for..of Javascript.

Nous allons modifier notre code pour basculer les utilisateurs dans un tableau côté TS sur lequel on bouclera côté HTML.

Modifions le fichier app.component.ts:

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

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

  users: Array<any>;

  constructor() {

    this.users= [
      {
        firstName: 'Thomas',
        lastName: 'CHEVALIER',
        age: 35
      },
      {
        firstName: 'Pierre',
        lastName: 'DUPONT',
        age: 46
      }
    ];

  }

  showAge(age: number) {
    alert(age);
  }

}

Nous pouvons voir que la directive *ngFor se positionne sur l’élément que l’on souhaite dupliquer grâce à la boucle.

Les directives par attribut

Contrairement aux directives structurelles, les directives par attribut vont permettre de modifier un composant une fois qu’il aura été créé.

On reconnait plusieurs de ces directives mais on va en aborder 2:

  • ngStyle pour assigner dynamiquement du style
  • ngClass pour assigner dynamiquement des classes

Utilisation de ngStyle

L’attribut ngStyle permet d’appliquer du style de manière dynamique sur un élément.

C’est un attribut mis à disposition par Angular qui acceptera un objet Javascript dont les clés seront les propriétés CSS et les valeurs, les valeurs à appliquer.

Cet attribut accepte évidemment le property binding et va nous permettre par exemple d’utiliser une fonction pour renvoyer un style généré selon certaines conditions.

Reprenons notre composant who-am-i.component.

Lorsque je boucle avec le *ngFor, je peux récupérer sur chaque boucle, l’index du tableau sur lequel je me trouve.

Nous allons faire en sorte de mettre en majuscule les index impairs et en minuscule les index pairs.

Première solution sans utiliser de fonction.

Modifions le fichier app.component.html:

<router-outlet></router-outlet>

<app-who-am-i
  *ngFor="let user of users, index as i"
  [ngStyle]="{textTransform: i % 2 === 0 ? 'lowercase' : 'uppercase'}"
  (showAgeClicked)="showAge(user.age)"
  [firstName]="user.firstName"
  [lastName]="user.lastName">
</app-who-am-i>

N.B: On notera que la propriété CSS, lorsqu’elle est composée (c’est à dire avec un “-”, s’écrira au format camelCase. (par exemple la propriété “text-transform” s’écrira “textTransform”)

Deuxième solution en utilisant une fonction.

Modifions le fichier app.component.ts:

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

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

  users: Array<any>;

  constructor() {

    this.users= [
      {
        firstName: 'Thomas',
        lastName: 'CHEVALIER',
        age: 35
      },
      {
        firstName: 'Pierre',
        lastName: 'DUPONT',
        age: 46
      }
    ];

  }

  showAge(age: number) {
    alert(age);
  }

  generateStyles(index: number): any {
    const styles = {
      textTransform: 'lowercase'
    };

    if(index % 2 !== 0) {
      styles.textTransform = 'uppercase';
    }

    return styles;
  }
}

Et modifions aussi le fichier app.component.html:

<router-outlet></router-outlet>

<app-who-am-i
  *ngFor="let user of users, index as i"
  [ngStyle]="generateStyles(i)"
  (showAgeClicked)="showAge(user.age)"
  [firstName]="user.firstName"
  [lastName]="user.lastName">
</app-who-am-i>

Utilisation de ngClass

L’attribut ngClass permet d’attribuer dynamiquement des classes à un élément.

Tout comme le ngStyle, c’est un élément qui est mis à disposition par Angular.

Son fonctionnement est le suivant: il accepte un objet dans lequel les clés seront les classes à appliquer et les valeurs seront les conditions pour appliquer les clés.

Reprenons notre composant who-am-i.component.

Tout comme nous avons changé en dur le nom ‘Thomas’ en ‘Tom’, nous allons faire en sorte que le bouton apparaisse d’une manière différente si nous sommes sur un utilisateur qui porte le nom ‘Thomas’.

Rendez-vous dans le fichier who-am-i.component.html:

<div *ngIf="firstName === 'Thomas'">Hey, mon nom est Tom {{lastName}}</div>
<div *ngIf="firstName !== 'Thomas'">Hey, mon nom est {{firstName}} {{lastName}}</div>
<button
  (click)="onClickShowAge()"
  [hidden]="isAgeHidden"
  class="btn"
  [ngClass]="{
		'btn-dark': firstName === 'Thomas', 
		'btn-outline-dark': firstName !== 'Thomas'
	}">Afficher mon âge !
</button>

Le résultat obtenu:

Attention, pour obtenir ce résultat, j’ai utilisé Bootstrap dans mon projet. Tu peux aussi simplement créer ta propre classe dans ton fichier css et l’affecter tout simplement.

Conclusion

Les bases fondamentales à apprendre en Angular sont assez nombreuses dans un premier temps mais permettront, une fois bien prises en main, de travailler extrêmement rapidement et d’être très productif.

Si tu souhaites être encadrer correctement dans ton apprentissage, je t’invite à rejoindre ma formation qui met à disposition des vidéos permettant d’aborder toutes les notions, des exercices pratiques ainsi que leur correction et de nombreux bonus. Nous t’attendons dès maintenant !

Thomas C

Formateur sur des parcours DWWM & CDA, j'ai décidé d'aller plus loin en te partageant mes connaissances en vitesse supersonic 🚀 Prends ta revanche sur la vie !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Formation Développeur Web