Cours Angular · Module 5: Services et DI

Les services dans Angular - Les guildes d'artisans

2 min de lecture
Dans cette leçon3

Les services dans Angular sont comme des guildes d'artisans : des unités spécialisées qui fournissent leurs services à tout le royaume. Chaque guilde a sa spécialité : les forgerons forgent les épées, les tailleurs cousent les kimonos.

Qu'est-ce qu'un service ?

Un service est une classe responsable de :

  • Logique métier - calculs, validations
  • Communication API - récupération/envoi de données
  • Gestion d'état - stockage de données entre les composants
  • Partage de code - éviter la duplication

Créer un service

1import { Injectable } from '@angular/core';
2
3@Injectable({
4  providedIn: 'root'  // Singleton disponible dans toute l'application
5})
6export class KatanaService {
7  private katanas: Katana[] = [];
8
9  getAll(): Katana[] {
10    return [...this.katanas]; // On retourne une copie
11  }
12
13  getById(id: number): Katana | undefined {
14    return this.katanas.find(k => k.id === id);
15  }
16
17  forge(name: string, type: string): Katana {
18    const katana: Katana = {
19      id: Date.now(),
20      name,
21      type,
22      damage: Math.floor(Math.random() * 100) + 50,
23      createdAt: new Date()
24    };
25    this.katanas.push(katana);
26    return katana;
27  }
28
29  destroy(id: number): boolean {
30    const index = this.katanas.findIndex(k => k.id === id);
31    if (index > -1) {
32      this.katanas.splice(index, 1);
33      return true;
34    }
35    return false;
36  }
37}

Générer via le CLI

1ng generate service services/katana
2# ou en version courte :
3ng g s services/katana
Code de cette leçon : src/app/app.component.ts
1import { Component, inject } from '@angular/core';
2import { SamuraiService } from './services/samurai.service';
3import { LoggerService } from './services/logger.service';
4
5@Component({
6  selector: 'app-root',
7  standalone: true,
8  template: `
9    <div class="guild-hall">
10      <header>
11        <h1>La guilde des artisans</h1>
12        <p>Module 5 : services et injection de dépendances</p>
13      </header>
14
15      <main>
16        <section class="info-panel">
17          <h2>À propos des services</h2>
18          <p>Les services sont des guildes d’artisans - des spécialistes de tâches précises.</p>
19          <ul>
20            <li>@Injectable() - enregistrement dans la DI</li>
21            <li>providedIn: 'root' - singleton</li>
22            <li>inject() - l’injection moderne</li>
23          </ul>
24        </section>
25
26        <section class="demo-panel">
27          <h2>Liste des samouraïs (depuis le service)</h2>
28          <div class="samurai-list">
29            @for (s of samuraiList; track s.id) {
30              <div class="samurai-card">
31                <strong>{{ s.name }}</strong>
32                <span>Clan : {{ s.clan }}</span>
33                <span>Niveau : {{ s.level }}</span>
34              </div>
35            }
36          </div>
37          <div class="actions">
38            <button (click)="addSamurai()">Ajouter un samouraï</button>
39            <button (click)="showLogs()">Afficher les logs</button>
40          </div>
41        </section>
42
43        <section class="logs-panel" *ngIf="logs.length">
44          <h3>Logs (depuis LoggerService)</h3>
45          <ul>
46            @for (log of logs; track $index) {
47              <li>{{ log }}</li>
48            }
49          </ul>
50        </section>
51      </main>
52    </div>
53  `,
54  styles: [`
55    .guild-hall {
56      font-family: 'Segoe UI', sans-serif;
57      max-width: 900px;
58      margin: 0 auto;
59      padding: 20px;
60      background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
61      min-height: 100vh;
62      color: #eee;
63    }
64    header {
65      text-align: center;
66      border-bottom: 2px solid #c9a227;
67      padding-bottom: 20px;
68    }
69    h1, h2, h3 { color: #c9a227; }
70    .info-panel, .demo-panel, .logs-panel {
71      background: rgba(255,255,255,0.05);
72      border: 1px solid #c9a227;
73      border-radius: 8px;
74      padding: 20px;
75      margin: 20px 0;
76    }
77    ul { list-style: none; padding: 0; }
78    li::before { content: "» "; }
79    .samurai-card {
80      background: #16213e;
81      border: 1px solid #333;
82      border-radius: 8px;
83      padding: 15px;
84      margin: 10px 0;
85      display: flex;
86      justify-content: space-between;
87    }
88    .actions {
89      display: flex;
90      gap: 10px;
91      margin-top: 15px;
92    }
93    button {
94      background: #c9a227;
95      color: #1a1a2e;
96      border: none;
97      padding: 10px 20px;
98      border-radius: 4px;
99      cursor: pointer;
100    }
101    button:hover { opacity: 0.9; }
102    .logs-panel ul {
103      background: #0d1117;
104      padding: 15px;
105      border-radius: 4px;
106      font-family: monospace;
107      font-size: 0.9rem;
108    }
109    .logs-panel li::before { content: "› "; color: #4ade80; }
110  `]
111})
112export class AppComponent {
113  private samuraiService = inject(SamuraiService);
114  private logger = inject(LoggerService);
115
116  samuraiList = this.samuraiService.getAll();
117  logs: string[] = [];
118
119  addSamurai() {
120    const newSamurai = {
121      id: Date.now(),
122      name: 'Nouveau guerrier',
123      clan: 'Ronin',
124      level: 1
125    };
126    this.samuraiService.add(newSamurai);
127    this.samuraiList = this.samuraiService.getAll();
128    this.logger.log('Nouveau samouraï ajouté : ' + newSamurai.name);
129  }
130
131  showLogs() {
132    this.logs = this.logger.getLogs();
133  }
134}

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. Quel décorateur marque une classe comme service dans Angular ?

  2. 2. D'après la leçon, de quoi un Service est-il responsable dans Angular ?

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 sur une seule ligne l'import du décorateur Injectable :

  • Éditeur de code

    Complète SamuraiService pour qu'Angular puisse l'injecter et crée une seule instance partagée pour toute l'application.

  • Clique dans l'ordre

    Clique dans l'ordre pour construire la commande Angular CLI qui génère un service :

Articles utiles