Le moyen le plus rapide d’apprendre Angular, c’est de construire quelque chose de petit du début à la fin. Sur cette page, vous construisez une liste de lecture : vous partez d’un composant qui affiche trois titres et arrivez à une application qui garde vos livres d’une visite à l’autre. Chaque étape ajoute une seule idée et renvoie à la page qui l’explique en détail.
Dans le labo, l’application de gauche exécute le code de droite. Lisez le code, jouez avec l’application, puis passez à l’étape suivante.
Créer le projet
L’Angular CLI crée le projet, génère les fichiers et lance un serveur de développement qui recharge la page à chaque enregistrement. Les nouveaux projets en v22 utilisent des composants standalone, des signals et plus de Zone.js — exactement ce qu’utilise cette page.
npm install -g @angular/cli
ng new reading-list # composants standalone, zoneless et signals par défaut
cd reading-list
ng generate component reading-list
ng serve # http://localhost:4200La construire en six étapes
Chaque étape est un vrai composant. Changez quelque chose dans l’application en direct, puis cherchez dans le code la ligne qui l’a provoqué.
Un composant, c’est une classe et un template. L’état est un signal qui contient trois livres, et @for dessine une ligne par livre.
Mes livres
- Frankenstein
- Dracula
- Moby-Dick
import { Component, signal } from '@angular/core';
interface Book {
id: number;
title: string;
read: boolean;
}
@Component({
selector: 'app-reading-list',
template: `
<h3>Mes livres</h3>
<ul>
<!-- track : comment Angular distingue les lignes -->
@for (book of books(); track book.id) {
<li>{{ book.title }}</li>
}
</ul>
`,
})
export class ReadingList {
// l’état : un signal qui contient une liste
protected readonly books = signal<Book[]>([
{ id: 1, title: 'Frankenstein', read: true },
{ id: 2, title: 'Dracula', read: false },
{ id: 3, title: 'Moby-Dick', read: false },
]);
}Ce que vous avez utilisé
| Étape | Notions | Pour aller plus loin |
|---|---|---|
| 1. Afficher une liste | un composant, signal(), @for avec track | Signals · Control flow |
| 2. Ajouter des livres | [value], (input), (keydown.enter), update() | Data binding |
| 3. Marquer comme lu | computed(), @if, @empty | Signals · Control flow |
| 4. Découper en composants | input.required(), output() | input() et output() |
| 5. Déplacer l’état dans un service | @Service(), inject(), asReadonly() | Services |
| 6. Enregistrer et filtrer | effect(), localStorage, un filtre en computed | effect() · Listes · Code compatible SSR |
Quatre bugs que tout le monde écrit une fois
Ce sont les bugs qu’on retrouve dans presque toutes les premières applications Angular. Activez-les un par un, voyez le symptôme de vos propres yeux, puis lisez pourquoi il se produit.
- Frankenstein
- Dracula
- Moby-Dick
Essayez : appuyez sur Ajouter « Hamlet » avec le bug actif. La liste affiche quatre livres, mais le computed et le composant OnPush en annoncent toujours trois. Réinitialiser remet tout d’aplomb d’un coup.
Pourquoi : push() modifie le tableau que le signal contient déjà. Le signal compare les références, voit le même tableau et ne prévient personne ; la liste n’a l’air juste que parce que le clic a rendu à nouveau ce composant-là. Donnez au signal un nouveau tableau : update((list) => [...list, book]).
// ✗ le même tableau, modifié sur place : le signal voit la même référence et ne prévient personne
this.books().push(book);
// ✓ un nouveau tableau : le signal prévient tous ceux qui le lisent
this.books.update((list) => [...list, book]);Les quatre ont la même racine : Angular fait confiance à ce que vous lui dites. Un signal croit qu’une nouvelle valeur signifie une nouvelle référence, track croit en votre clé, et un computed croit qu’il ne fait que calculer. Tenez ces promesses, et le framework fait le reste.
Et ensuite
- Une page par livre, avec sa propre URL : le routing.
- Un vrai formulaire avec validation pour ajouter des livres : Signal Forms.
- Des livres chargés depuis un serveur : HttpClient et resource().
- Des tests pour le store et les composants : les tests.
- Où ranger les fichiers quand l’application grandit : la structure des dossiers.