Angular 17 : @if, @for, @switch — le nouveau control flow

🏷️ Front-end 📅 12/04/2026 13:00:00 👤 Mezgani said
Angular Angular 17 Control Flow Template
Angular 17 : @if, @for, @switch — le nouveau control flow

Découvrez le nouveau système de control flow d'Angular 17 : remplacez *ngIf, *ngFor et ngSwitch par la syntaxe native @if, @for et @switch.

Introduction

Angular 17 introduit un nouveau système de control flow directement intégré dans le compilateur Angular. Fini les directives structurelles *ngIf, *ngFor et ngSwitch qui nécessitaient des imports spécifiques — la nouvelle syntaxe @if, @for et @switch est native, plus lisible et plus performante.

A retenir : Le nouveau control flow fait partie du compilateur Angular lui-même, pas d'une bibliothèque externe. Il est disponible dès Angular 17 et devient la syntaxe recommandée.

Le bloc @if

Le bloc @if remplace *ngIf avec une syntaxe plus naturelle. Il supporte également @else if et @else directement.

<!-- Ancien style avec *ngIf -->
<div *ngIf="isLoggedIn; else guestBlock">
  Bienvenue, {{ user.name }}
</div>
<ng-template #guestBlock>
  <div>Veuillez vous connecter</div>
</ng-template>

<!-- Nouveau style avec @if -->
@if (isLoggedIn) {
  <div>Bienvenue, {{ user.name }}</div>
} @else {
  <div>Veuillez vous connecter</div>
}

On peut également chaîner plusieurs conditions avec @else if :

@if (status === 'loading') {
  <app-spinner />
} @else if (status === 'error') {
  <app-error [message]="errorMsg" />
} @else {
  <app-content [data]="data" />
}
A retenir : Avec @if, plus besoin de <ng-template #else> — le bloc @else est inline, ce qui simplifie grandement les templates.

Le bloc @for

Le bloc @for remplace *ngFor et introduit une clause @empty très pratique pour afficher un fallback quand la liste est vide. La variable track est obligatoire pour optimiser les performances du rendu.

<!-- Ancien style avec *ngFor -->
<ul>
  <li *ngFor="let item of items; trackBy: trackById">
    {{ item.name }}
  </li>
</ul>

<!-- Nouveau style avec @for -->
<ul>
  @for (item of items; track item.id) {
    <li>{{ item.name }}</li>
  } @empty {
    <li>Aucun élément à afficher.</li>
  }
</ul>

Des variables implicites sont disponibles dans le bloc @for :

@for (item of items; track item.id; let i = $index, last = $last) {
  <div [class.last]="last">
    {{ i + 1 }}. {{ item.name }}
  </div>
}
Variables implicites : $index, $first, $last, $even, $odd, $count sont disponibles dans chaque bloc @for.

Le bloc @switch

Le bloc @switch remplace la directive [ngSwitch] et ses directives enfants *ngSwitchCase et *ngSwitchDefault.

<!-- Ancien style avec ngSwitch -->
<div [ngSwitch]="userRole">
  <admin-panel *ngSwitchCase="'admin'" />
  <editor-panel *ngSwitchCase="'editor'" />
  <viewer-panel *ngSwitchDefault />
</div>

<!-- Nouveau style avec @switch -->
@switch (userRole) {
  @case ('admin') {
    <admin-panel />
  }
  @case ('editor') {
    <editor-panel />
  }
  @default {
    <viewer-panel />
  }
}

Migration depuis les directives

Angular fournit un schematic de migration automatique pour convertir les anciens templates vers le nouveau control flow :

ng generate @angular/core:control-flow

Ce schematic scanne tous vos templates et remplace automatiquement *ngIf, *ngFor et [ngSwitch] par leurs équivalents @if, @for et @switch.

A retenir : La migration automatique fonctionne bien dans la plupart des cas. Vérifiez les cas complexes avec as et les templates nommés qui peuvent nécessiter un ajustement manuel.

Avantages du nouveau control flow

  • Plus de bundle size : les directives NgIf, NgFor, NgSwitch ne sont plus nécessaires dans les imports des composants.
  • Meilleures performances : le compilateur optimise directement le rendu sans passer par les directives.
  • Lisibilité améliorée : la syntaxe ressemble à du code TypeScript natif, plus intuitive pour les nouveaux développeurs.
  • @empty intégré : gérez les listes vides sans *ngIf="items.length === 0" séparé.
  • @else if natif : enchaînez des conditions sans imbrications de templates.