Skip to content

*ngIf: Comment l'utiliser dans Angular

Préalablement: Ajoutons CommonModule

Pour utiliser le cette directive, vous devez d'abord inclure CommonModule dans votre application en l'ajoutant à la liste des imports dans votre fichier de module principal

ts
import { CommonModule } from '@angular/core';

@NgModule({
  declarations: [
    // Ici, le composant qui contient la directive
  ],
  imports: [
    // ... autre modules
    CommonModule
  ],
})
export class MonModule { }
import { CommonModule } from '@angular/core';

@NgModule({
  declarations: [
    // Ici, le composant qui contient la directive
  ],
  imports: [
    // ... autre modules
    CommonModule
  ],
})
export class MonModule { }

Si vous mettez pas le module, vous aurez l'erreur suivante: Can't bind to '<nom de la directive>' since it isn't a known property of 'div'

## Introduction à ngIf dans Angular

*ngIf est une directive structurelle qui permet d'afficher ou de masquer un élément HTML en fonction d'une expression booléenne. Si l'expression est vraie, l'élément est affiché. Si l'expression est fausse, l'élément est masqué. *ngIf est une directive structurelle, ce qui signifie qu'elle modifie la structure du DOM. Cela signifie que l'élément HTML auquel *ngIf est appliqué est ajouté ou supprimé du DOM en fonction de l'expression booléenne.


## Utilisation basique de ngIf

ngIf est une directive structurale. Cela signifie qu'elle modifie la structure du DOM (elle ajoute ou retire des éléments). Voici un exemple simple :

html
<p *ngIf="showMessage">
  Bienvenue sur notre site !
</p>
<p *ngIf="showMessage">
  Bienvenue sur notre site !
</p>

Si la variable showMessage est true, le paragraphe sera présent dans le DOM et affiché à l'utilisateur. Si showMessage est false, le paragraphe sera complètement retiré du DOM.

Différence avec [hidden]

[hidden] est une autre façon d'afficher ou de masquer des éléments, mais son fonctionnement est différent. Au lieu de retirer ou d'ajouter des éléments au DOM, il modifie simplement la propriété CSS display de l'élément. Exemple :

html
<p [hidden]="!showMessage">
  Bienvenue sur notre site !
</p>
<p [hidden]="!showMessage">
  Bienvenue sur notre site !
</p>

Si showMessage est true, le paragraphe sera visible, car la propriété [hidden] sera évaluée à false. Si showMessage est false, le paragraphe sera masqué (mais toujours présent dans le DOM) car [hidden] sera évalué à true.


Donc:

  • ngIf : Ajoute ou retire l'élément du DOM en fonction de la condition.
  • [hidden] : Masque visuellement l'élément en modifiant le CSS, mais l'élément reste dans le DOM.

L'utilisation de l'une ou l'autre dépend de vos besoins. Si vous souhaitez optimiser les performances en évitant d'avoir des éléments inutiles dans le DOM, ngIf peut être préférable. Si vous prévoyez de montrer et de masquer fréquemment un élément et que la performance de cette opération est cruciale, [hidden] pourrait être une meilleure option.

La syntaxe ngIf et else

La directive ngIf est utilisée pour afficher ou masquer des éléments du DOM en fonction d'une condition.

html
<div *ngIf="condition; else elseBlock">
    Affiché si la condition est vraie
</div>

<ng-template #elseBlock>
    Affiché si la condition est fausse
</ng-template>
<div *ngIf="condition; else elseBlock">
    Affiché si la condition est vraie
</div>

<ng-template #elseBlock>
    Affiché si la condition est fausse
</ng-template>

Dans cet exemple, si la variable condition est true, le div sera affiché. Si false, le contenu de elseBlock sera affiché.

La syntaxe ngIf, then et else

Cette syntaxe offre une manière plus explicite de gérer les deux cas.

html
<div *ngIf="condition; then thenBlock else elseBlock"></div>

<ng-template #thenBlock>
    Affiché si la condition est vraie
</ng-template>

<ng-template #elseBlock>
    Affiché si la condition est fausse
</ng-template>
<div *ngIf="condition; then thenBlock else elseBlock"></div>

<ng-template #thenBlock>
    Affiché si la condition est vraie
</ng-template>

<ng-template #elseBlock>
    Affiché si la condition est fausse
</ng-template>

Utilisation des données observables avec ngIf et le pipe async

Vous pouvez utiliser ngIf avec des Observables en utilisant le pipe async.

html
<div *ngIf="observableData$ | async as data">
    {{ data }}
</div>
<div *ngIf="observableData$ | async as data">
    {{ data }}
</div>

Dans cet exemple, observableData$ est un observable. Le pipe async s'abonne à l'observable et renvoie la dernière valeur émise.

Comment ngIf fonctionne-t-il en interne ?

  • ngIf utilise <ng-template> pour marquer le lieu où le contenu conditionnel doit être affiché ou masqué.
  • Lorsque la condition est true, Angular crée une vue pour le contenu de <ng-template> et l'insère dans le DOM.
  • Lorsque la condition est false, Angular détruit cette vue et retire le contenu du DOM.

Il est important de comprendre ce qu'est <ng-template>. En Angular, un <ng-template> est un élément qui définit un modèle. Ce modèle ne sera pas rendu par défaut dans le DOM. C'est un peu comme une esquisse ou un projet : il décrit quelque chose qui pourrait exister, mais qui n'existe pas encore.

Quand vous utilisez *ngIf, même si vous ne voyez pas directement l'élément <ng-template>, Angular le crée en coulisse. C'est ce qui permet à Angular de comprendre où le contenu conditionnel doit être placé, sans l'afficher immédiatement.

  1. Dès qu'Angular détecte la directive *ngIf, il évalue la condition fournie. Si cette condition est true, Angular sait qu'il doit rendre le contenu associé.
  2. Si la condition évaluée est true :
  • Angular utilise le modèle défini à l'intérieur de <ng-template> pour créer une "vue".
  • Une "vue" en Angular n'est rien d'autre qu'une portion du DOM avec ses éléments, ses données et sa logique associée.
  • Une fois cette vue créée, Angular l'insère activement dans le DOM. C'est à ce moment que vous commencez à voir le contenu sur la page.
  1. Si la condition devient false ou si elle est évaluée comme fausse dès le départ :
  • Angular retire la vue correspondante du DOM. Cela signifie que non seulement le contenu n'est pas visible, mais il n'est même pas présent dans le DOM.
  • La destruction de la vue libère également les ressources associées, ce qui est bénéfique pour les performances.

Utiliser ngFor et ngIf simultanément est courant dans les applications Angular pour afficher une liste d'éléments basée sur certaines conditions. Voici comment vous pouvez les utiliser ensemble.

Combinaison de ngFor avec ngIf

Disons que nous avons une liste de produits et que nous voulons seulement afficher ceux qui sont en stock :

typescript
// dans un composant
products = [
  { name: 'Ordinateur', inStock: true },
  { name: 'Téléphone', inStock: false },
  { name: 'Tablette', inStock: true }
];
// dans un composant
products = [
  { name: 'Ordinateur', inStock: true },
  { name: 'Téléphone', inStock: false },
  { name: 'Tablette', inStock: true }
];

Avec ngFor et ngIf, nous pouvons faire :

html
<ul>
  <li *ngFor="let product of products" *ngIf="product.inStock">
    {{ product.name }}
  </li>
</ul>
<ul>
  <li *ngFor="let product of products" *ngIf="product.inStock">
    {{ product.name }}
  </li>
</ul>

Cependant, la combinaison directe de ngFor et ngIf sur le même élément, comme ci-dessus, entraînera une erreur car Angular ne permet pas d'utiliser deux directives structurales sur le même élément.

Solution : Utiliser <ng-container>

Pour contourner cette limitation, nous pouvons utiliser <ng-container>, qui est un élément de groupe qui n'affecte pas la mise en page ou le style :

html
<ul>
  <ng-container *ngFor="let product of products">
    <li *ngIf="product.inStock">
      {{ product.name }}
    </li>
  </ng-container>
</ul>
<ul>
  <ng-container *ngFor="let product of products">
    <li *ngIf="product.inStock">
      {{ product.name }}
    </li>
  </ng-container>
</ul>

Dans cet exemple :

  • Le <ng-container> est utilisé pour répéter chaque produit.
  • La directive ngIf est ensuite utilisée pour vérifier si le produit est en stock avant de l'afficher.

Ainsi, le rendu final de cette liste ne montrera que les produits qui sont en stock.

Astuce: Utilisation d'un filtre au niveau du composant

Dans certains cas, pour optimiser les performances ou simplifier le template, il pourrait être utile de filtrer les données directement dans le composant :

typescript
get productsInStock() {
  return this.products.filter(product => product.inStock);
}
get productsInStock() {
  return this.products.filter(product => product.inStock);
}

Et dans le template :

html
<ul>
  <li *ngFor="let product of productsInStock">
    {{ product.name }}
  </li>
</ul>
<ul>
  <li *ngFor="let product of productsInStock">
    {{ product.name }}
  </li>
</ul>

Cette approche réduit la complexité du template et augmente la lisibilité.