Cours Angular · Module 7: RxJS

La gestion des abonnements

2 min de lecture
Dans cette leçon4

Les fuites de mémoire causées par des abonnements non terminés sont un problème sérieux - comme un ninja qui aurait oublié de revenir de sa mission !

takeUntilDestroyed (Angular 16+) - Recommandé

1import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2import { DestroyRef, inject } from '@angular/core';
3
4@Component({...})
5export class ModernComponent {
6  private destroyRef = inject(DestroyRef);
7
8  constructor() {
9    // Se termine automatiquement quand le composant est détruit
10    this.dataService.getData().pipe(
11      takeUntilDestroyed()
12    ).subscribe(data => {
13      this.processData(data);
14    });
15
16    // Peut aussi être utilisé en dehors du constructeur
17    this.loadData();
18  }
19
20  loadData(): void {
21    this.http.get('/api/data').pipe(
22      takeUntilDestroyed(this.destroyRef)
23    ).subscribe();
24  }
25}

L'approche traditionnelle avec Subject

1import { Subject } from 'rxjs';
2import { takeUntil } from 'rxjs/operators';
3
4@Component({...})
5export class TraditionalComponent implements OnDestroy {
6  private destroy$ = new Subject<void>();
7
8  ngOnInit(): void {
9    this.dataService.getData().pipe(
10      takeUntil(this.destroy$)
11    ).subscribe(data => {
12      this.processData(data);
13    });
14
15    // Abonnements multiples
16    this.otherService.getOther().pipe(
17      takeUntil(this.destroy$)
18    ).subscribe();
19  }
20
21  ngOnDestroy(): void {
22    this.destroy$.next();
23    this.destroy$.complete();
24  }
25}

AsyncPipe - Gestion automatique

1@Component({
2  template: `
3    @if (samuraiList$ | async; as samuraiList) {
4      @for (s of samuraiList; track s.id) {
5        <div>{{ s.name }}</div>
6      }
7    } @else {
8      <p>Loading...</p>
9    }
10  `
11})
12export class SamuraiListComponent {
13  // AsyncPipe s'abonne et se désabonne automatiquement !
14  samuraiList$ = this.http.get<Samurai[]>('/api/samurai');
15}

La collection d'abonnements

1import { Subscription } from 'rxjs';
2
3@Component({...})
4export class CollectionComponent implements OnDestroy {
5  private subscriptions = new Subscription();
6
7  ngOnInit(): void {
8    // Ajoute les abonnements à la collection
9    this.subscriptions.add(
10      this.service1.data$.subscribe()
11    );
12
13    this.subscriptions.add(
14      this.service2.data$.subscribe()
15    );
16  }
17
18  ngOnDestroy(): void {
19    // Une seule ligne annule tout
20    this.subscriptions.unsubscribe();
21  }
22}

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quelle est la façon recommandée de gérer les abonnements dans Angular 16+ ?

  2. 2. Que fait AsyncPipe automatiquement ?

Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.

Tâches pratiques dans le jeu

  • Tri horizontal

    Ordonne l'import de l'opérateur takeUntilDestroyed depuis le package interop :

  • Éditeur de code

    Complète le code pour que l'abonnement à interval() se termine tout seul quand le composant est détruit.

  • Tri vertical

    Ordonne les étapes du pattern traditionnel de nettoyage d'abonnement avec Subject, dans l'ordre où elles apparaissent dans un composant :

  • Clique dans l'ordre

    Ordonne l'expression AsyncPipe avec un alias dans un template : samurai$ | async; as samurai

Articles utiles