Skip to content

Faire fonctionner signal avec RxJS

L'interopérabilité RxJS fait référence à la capacité d'intégration entre les signaux d'Angular et la bibliothèque RxJS. Cela signifie que vous pouvez facilement utiliser les fonctionnalités et les opérateurs de RxJS avec les signaux d'Angular, et vice versa.

Voici quelques points importants concernant l'interopérabilité RxJS :

  1. Conversion de signaux en observables : Vous pouvez utiliser la fonction toObservable de @angular/core/rxjs-interop pour convertir un signal en un observable. Cela vous permet d'appliquer des opérations RxJS sur le signal, comme utiliser les opérateurs de transformation de flux, effectuer des filtrages, etc.

  2. Conversion d'observables en signaux : Vous pouvez utiliser la fonction toSignal de @angular/core/rxjs-interop pour convertir un observable en un signal. Cela vous permet de bénéficier des fonctionnalités des signaux, telles que la déclaration de dépendances, la gestion automatique des mises à jour et les effets.

  3. Utilisation des opérateurs RxJS avec les signaux : Une fois que vous avez converti un signal en observable, vous pouvez utiliser tous les opérateurs RxJS pour manipuler les flux de données. Cela inclut des opérateurs tels que map, filter, debounceTime, switchMap, etc. Vous pouvez ainsi effectuer des transformations complexes et des opérations sur les signaux.

  4. Intégration des fonctionnalités avancées de RxJS : L'interopérabilité RxJS vous permet également de tirer parti des fonctionnalités avancées de RxJS, telles que la gestion fine des abonnements avec les opérateurs takeUntil, retry, debounce, etc. Cela facilite la gestion de la durée des abonnements aux signaux et l'annulation des abonnements lorsque cela est nécessaire.

Exemple d'une ToDoList

D'après la reprise du code sur la chapite Les signals, computed et effects dans Angular 16+. voici comment vous pouvez utiliser RxJS avec les signaux :

typescript
import { Component } from '@angular/core';
import { signal, toObservable } from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-todo-list',
  template: `
    <h2>Ma liste de tâches</h2>

    <ul>
      <li *ngFor="let task of tasks">
        {{ task.description }} 
        <button (click)="markTaskAsCompleted(task)">Terminée</button>
      </li>
    </ul>

    <p>Nombre de tâches terminées : {{ count$ | async }}</p>
  `,
})
export class TodoListComponent {
  tasks = [
    { description: 'Faire les courses', isCompleted: false },
    { description: 'Nettoyer la maison', isCompleted: false },
    { description: 'Répondre aux e-mails', isCompleted: false },
  ];

  count = signal(0);
  count$ = toObservable(this.count);

  markTaskAsCompleted(task: any) {
    task.isCompleted = true;
    this.count.set(this.count() + 1);
  }
}
import { Component } from '@angular/core';
import { signal, toObservable } from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-todo-list',
  template: `
    <h2>Ma liste de tâches</h2>

    <ul>
      <li *ngFor="let task of tasks">
        {{ task.description }} 
        <button (click)="markTaskAsCompleted(task)">Terminée</button>
      </li>
    </ul>

    <p>Nombre de tâches terminées : {{ count$ | async }}</p>
  `,
})
export class TodoListComponent {
  tasks = [
    { description: 'Faire les courses', isCompleted: false },
    { description: 'Nettoyer la maison', isCompleted: false },
    { description: 'Répondre aux e-mails', isCompleted: false },
  ];

  count = signal(0);
  count$ = toObservable(this.count);

  markTaskAsCompleted(task: any) {
    task.isCompleted = true;
    this.count.set(this.count() + 1);
  }
}

Dans cet exemple, nous utilisons la fonction toObservable de @angular/core/rxjs-interop pour convertir le signal count en un observable count$. Cela nous permet d'utiliser l'opérateur pipe et l'async pipe (| async) dans le template pour souscrire automatiquement aux mises à jour du signal et afficher la valeur.

Lorsque markTaskAsCompleted est appelée, nous mettons à jour la propriété isCompleted de la tâche correspondante et nous augmentons la valeur du signal count en utilisant this.count.set(this.count() + 1).

Ainsi, à chaque fois qu'une tâche est marquée comme terminée, le signal count est mis à jour et la valeur est automatiquement reflétée dans le template grâce à l'async pipe.