Les nouveautés d'Angular 19 en 4 minutes

Angular 19 vient de sortir, et il y a beaucoup de nouveautés intéressantes : hydratation incrémentale, linkedSignal, l'API des ressources, et plein d'autres choses. Venez découvrir tout ça en moins de 4 minutes !

Skip to content

Vous souhaitez recevoir de l'aide sur ce sujet ? rejoignez la communauté Angular.fr sur Discord.

Ho, cette partie n'est plus d'actualité ! 👀

Depuis Angular 17, Utilisez les contrôles de flux comme @if, @for ou @switch. C'est beaucoup plus simple et plus lisible. Pour en savoir plus, consultez Contrôles de flux.

Savoir utiliser la directive *ngFor

Préalablement: Ajoutons CommonModule

Pour utiliser le cette directive, vous devez d'abord inclure CommonModule dans votre composant:

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

@Component({
  selector: 'app-mon-composant',
  template: `
    <!-- Mettez ici le template de votre composant -->
  `,
  standalone: true,
  imports: [
    CommonModule
  ],
})
export class MyComponent { }

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'

ngFor est une directive importante pour votre application. Pourquoi ? Car vous recevez généralement des données de la part du serveur, et vous devez les afficher côté frontend :

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

@Component({
  selector: 'app',
  template: `
    <p *ngFor="let user of users">{{user.name}} : {{user.age}}</p>
  `
})
export class AppComponent {
  users: any[] = [
    {name: 'Sam', age: 45},
    {name: 'Jim', age: 33},
    {name: 'Ana', age: 17},
    {name: 'Lou', age: 4},
  ]
}

Ici, nous avons un tableau d'utilisateurs (directement dans le code, mais nous pouvons imaginer que ces données seront récupérées sur un serveur par la suite).

La valeur de ngFor reprend la syntaxe d'une boucle Javascript. La variable locale user n'est utilisable que dans l'élément ayant ngFor

Utiliser d'autres variables locales

Il est parfois très utiliser de connaitre l'index, par exemple, pour afficher une numérotation à chaque tour de boucle. Il existe donc 5 variables locales :

  • index : position de l'item. Commence à 0.
  • first : booléen indiquant si l'item est le premier de l'itération
  • last : booléen indiquant si l'item est le dernier de l'itération
  • even : booléen indiquant si la position de l'item est paire
  • odd : booléen indiquant si la position de l'item est impaire

Voici un code illustrant leur utilisation :

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

@Component({
  selector: 'app',
  styles: [
    `
      .red {
        color: red;
      }
    `
  ],
  template: `
    <p *ngFor="let user of users ; let i = index ; let isEven = even" [ngClass]="{red: isEven}">
     N°{{i}} --> {{user.name}} : {{user.age}}
    </p>
  `
})
export class AppComponent {
  users: any[] = [
    {name: 'Sam', age: 45},
    {name: 'Jim', age: 33},
    {name: 'Ana', age: 17},
    {name: 'Lou', age: 4},
  ]
}

Les variables locales sont présentes dans ngFor. Nous déclarons des nouvelles variables pour utiliser ces fameuses variables locales. Nous mixons notre boucle avec d'autres directives. Ici, lorsque l'index est pair alors l'élément est coloré en rouge.

Utiliser trackBy pour améliorer la performance

Nous allons utiliser un exemple pour se rendre compte de l'utilité de trackBy.

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

@Component({
  selector: 'app',
  template: `
    <p *ngFor="let user of users">
      <user>
        {{user.name}} : {{user.age}}
      </user>
    </p>
    <button (click)="add()">Ajouter</button>
  `
})
export class AppComponent {

  users: any[] = [
    {name: 'Sam', age: 45, id: 1},
    {name: 'Jim', age: 33, id: 2},
    {name: 'Ana', age: 17, id: 3},
    {name: 'Lou', age: 4,  id: 4},
  ];

  add() {
    let newIndex = this.users.length+1;
    this.users = this.users.map((obj) => {
      return Object.assign({}, obj);
    })
    this.users.push({name: `Test${newIndex}`, age: 15, id: newIndex});
  }
}

Notre composant permet d'afficher les utilisateurs. Rien de nouveau. Nous avons ajouté un bouton ajoutant un nouvel utilisateur.

Le tableau users a été cloné (en créant un objet immutable). Le tableau n'étant plus le même que l'initial, Angular va supprimer tous les éléments dans le DOM et les récréer d'une manière itérative. Pour se rendre compte, nous avons créer un composant enfant :

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

@Component({
  selector: 'user',
  template: `
    <ng-content></ng-content>
  `
})
export class UserComponent {
  ngOnInit() {
    console.log('Utilisateur créé')
  }

  ngOnDestroy() {
    console.log('Utilisateur supprimé')
  }
}

Effectivement, qiand nous ajoutons un utilisateur, les logs sont appelés plusieurs fois : 4 suppressions et 5 créations ensuite. Imaginez la même chose mais avec 10000 utilisateurs...

Pour éviter cela, nous utilisons trackBy qui mémorise les items selon une propriété unique. Très généralement, cette propriété est l'ID. Voici comment nous l'utilisons :

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

@Component({
  selector: 'app',
  template: `
    <p *ngFor="let user of users ; trackBy: trackById">
      <user>
        {{user.name}} : {{user.age}}
      </user>
    </p>
    <button (click)="add()">Ajouter</button>
  `
})
export class AppComponent {

  users: any[] = [
    {name: 'Sam', age: 45, id: 1},
    {name: 'Jim', age: 33, id: 2},
    {name: 'Ana', age: 17, id: 3},
    {name: 'Lou', age: 4,  id: 4},
  ];

  add() {
    let newIndex = this.users.length+1;
    // Create immutable object
    this.users = this.users.map((obj) => {
      return Object.assign({}, obj);
    })
    this.users.push({name: `Test${newIndex}`, age: 15, id: newIndex});
  }

  trackById(index: number, obj: any): number {
    return obj.id;
  }


}

Nous ajoutons donc trackBy dans ngFor avec la méthode à appeler (ici, trackById). Cette dernière envoie l'identifiant de l'item.

Si vous testez et regardez les logs, vous remarquez que nous avons qu'une création lors d'un ajout d'un utilisateur. Bien mieux !

Chaque mois, recevez en avant-première notre newsletter avec les dernières actualités, tutoriels, astuces et ressources Angular directement par email !