Cours Angular · Module 5: Services et DI

La communication entre composants via les services

2 min de lecture
Dans cette leçon2

Les services sont un excellent moyen pour les composants de communiquer entre eux - comme des messagers entre les châteaux.

Exemple : un service d'état partagé

1import { Injectable, signal, computed } from '@angular/core';
2
3export interface CartItem {
4  id: number;
5  name: string;
6  quantity: number;
7  price: number;
8}
9
10@Injectable({ providedIn: 'root' })
11export class CartService {
12  // État sous forme de signals
13  private items = signal<CartItem[]>([]);
14
15  // Valeurs calculées
16  readonly cartItems = this.items.asReadonly();
17  readonly totalItems = computed(() =>
18    this.items().reduce((sum, item) => sum + item.quantity, 0)
19  );
20  readonly totalPrice = computed(() =>
21    this.items().reduce((sum, item) => sum + item.price * item.quantity, 0)
22  );
23
24  addItem(item: Omit<CartItem, 'quantity'>): void {
25    const existing = this.items().find(i => i.id === item.id);
26    if (existing) {
27      this.items.update(items =>
28        items.map(i => i.id === item.id
29          ? { ...i, quantity: i.quantity + 1 }
30          : i
31        )
32      );
33    } else {
34      this.items.update(items => [...items, { ...item, quantity: 1 }]);
35    }
36  }
37
38  removeItem(id: number): void {
39    this.items.update(items => items.filter(i => i.id !== id));
40  }
41
42  clearCart(): void {
43    this.items.set([]);
44  }
45}

Utilisation dans les composants

1// header.component.ts - affiche le nombre d'articles
2@Component({
3  template: `<span>{{ cartService.totalItems() }}</span>`
4})
5export class HeaderComponent {
6  cartService = inject(CartService);
7}
8
9// product.component.ts - ajoute au panier
10@Component({
11  template: `<button (click)="addToCart()">Add</button>`
12})
13export class ProductComponent {
14  private cartService = inject(CartService);
15
16  addToCart(): void {
17    this.cartService.addItem({
18      id: this.product.id,
19      name: this.product.name,
20      price: this.product.price
21    });
22  }
23}

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. D'après la leçon, comment les composants peuvent-ils communiquer et partager leur état ?

  2. 2. Quelle fonction utiliseras-tu dans un service pour créer une valeur dérivée calculée automatiquement à partir d'autres signals ?

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

Tâches pratiques dans le jeu

  • Clique dans l'ordre

    Clique dans l'ordre pour construire l'expression qui expose un signal en lecture seule :

  • Éditeur de code

    Complète le service de communication qui utilise Signals pour partager l'état.

  • Clique dans l'ordre

    Clique dans l'ordre pour construire l'appel qui vide l'état du panier en définissant un tableau vide :

  • Tri vertical

    Ordonne la séquence d'opérations sur un service panier basé sur les signals :

  • Tri horizontal

    Ordonne sur une seule ligne la lecture du signal totalItems depuis le service dans le template (sans les accolades {{ }}) :

  • Tri vertical

    Ordonne la construction d'un composant qui utilise le CartService partagé :

Articles utiles