
Les Signals ont été introduits dans la version 17 d'Angular, et sont une révolution dans la gestion de state dans vos applications. Un Signal est un primitif réactif qui permet d'optimiser la mise à jour des données affichées dans les components. Non seulement ils facilitent la gestion de state avec une API simple, ils permettent au framework de savoir exactement comment mettre à jour le DOM à chaque modification de donnée.
Commençons par créer un Signal pour voir comment lire et mettre à jour la valeur qu'il contient.
Actuellement, dans l'en-tête de l'application, le titre et le tagline sont statiques, codés en dur. Je vous propose de changer cela en première découverte des Signals.
Danscore/layout/header, ouvrezheader.component.tset ajoutez une propriétéheaderà la classe comme suit :
header = signal<string>('Signalize');La fonctionsignal(importé depuis@angular/core) crée ce que l'on appelle un WritableSignal — un Signal dont vous pouvez modifier la valeur directement. Ici, vous déclarez que le Signal contiendra toujours des valeurs de typestring, et vous lui donnez une valeur initiale de Signalize.
Pour lire la valeur contenue dans un Signal, on "l'appelle", un peu comme une fonction. Dans le template, remplacez-le1codé en dur avec :
<h1 class="header">{{ header() }}</h1>Pour l'instant, dans le DOM, rien n'a changé :

Sauf que le titre peut maintenant être modifié dynamiquement. Utilisons unsetTimeoutdans un constructor pour le modifier au bout de 2 secondes grâce à sa méthodeset:
constructor() {
setTimeout(() => {
this.header.set('Signalize!');
}, 2000);
}Comme son nom l'indique,setdéfinit la valeur du Signal.
Il existe également la méthodeupdate, qui permet de mettre à jour la valeur d'un Signal à partir de sa valeur actuelle :
constructor() {
setTimeout(() => {
this.header.set('Signalize!');
}, 2000);
setTimeout(() => {
this.header.update(header => header + '!');
}, 3000);
}Comme ça, au bout de 3 secondes, on a :

Pour l'instant, ça n'a pas l'air d'apporter grand chose, surtout quand on sait qu'Angular permet le même comportement avec des variables classiques…
Mais ce n'est que le début !
Passons maintenant au tagline de l'en-tête. On souhaiterait que celui-ci change toutes les 5 secondes en tirant un tagline au sort à partir d'une collection fournie.
Commencez par ajouter le tableau de taglines à votre component :
private _taglines: string[] = [
`So your tasks aren't a chore to complete`,
`Organize your life with signals`,
`Task management made simple`,
`Stay productive with Signalize`
];Premièrement, on va créer un WritableSignal qui contiendra l'index aléatoire du tagline à afficher : on lui donnera une valeur initiale de 0 :
taglineIndex = signal<number>(0);Dans le constructor, utilisonssetIntervalpour lui donner une valeur aléatoire située entre 0 et 3 toutes les 5 secondes :
setInterval(() => {
this.taglineIndex.set(Math.floor(Math.random() * this._taglines.length));
}, 5000);Ce que nous souhaitons maintenant, c'est de générer un nouveau Signal, à partir de taglineIndex , qui contiendra le tagline qui correspond à l'index sélectionné. Pour cela, nous avons les Signals computed :
tagline = computed<string>(() => this._taglines[this.taglineIndex()]);Comme son nom l'indique,computedcrée un Signal dont la valeur est calculée à partir d'un ou plusieurs autres Signals. Lescomputedsont plutôt "magiques" : on n'a pas besoin de lister les Signals dont ils sont dépendants — ils sont capables de comprendre leurs dépendances à partir de leur utilisation.
Et ils sont totalement dynamiques et synchrones !
Dès quetaglineIndexchange sa valeur,taglinechange la sienne immédiatement.
Du coup, si vous modifiez votre template pour lire votre nouveau Signal :
<div class="header-container">
<h1 class="header">{{ header() }}</h1>
<p class="header-tagline">{{ tagline() }}</p>
</div>Vous verrez le résultat dans le DOM, avec le tagline qui change toutes les 5 secondes :

C'est déjà puissant ! On a un comportement réactif et dynamique, sans toute la complexité des Observables, et ce n'est que la première étape.

Le component ProgressComponent (dans tasks/components/progress ) contient des valeurs statiques pour les nombres de tâches et pour le remplissage de la barre de progression. Le but est de rendre les nombres dynamiques, et que le remplissage se calcule à partir de ces nombres.
Vous allez commencer par créer des Signals pour le nombre de tâches complétés et pour le nombre total de tâches. Ces Signals remplaceront les valeurs codés en dur.
Vous créerez un Signal qui dérive sa valeur des deux nombres pour régler le remplissage de la barre de progression. Il faut qu'il contienne des valeurs sous la forme'X%'pour qu'il puisse ensuite être lié auwidthde ladivde classeprogress-fill.
Un Signal est un primitif réactif qui simplifie la création de comportements dynamiques et améliore les performances.
On lit la valeur contenue dans un Signal en l'appelant comme une fonction : en y ajoutant des parenthèses()
Un WritableSignal est un Signal dont on peut modifier directement la valeur.
On crée un WritableSignal avec la fonctionsignalet on modifie sa valeur avecsetouupdate
Un Signalcomputeddérive sa valeur d'un ou plusieurs autres Signals.
Dans le prochain chapitre, regardons comment utiliser les Signals pour faire communiquer nos components.