Angular lève cette erreur lorsqu'on écrit dans un signal (avec set ou update) pendant l'évaluation d'un computed ou d'un template. Tous deux sont censés uniquement lire des signals ; y écrire modifierait donc l'état en plein calcul.
Le message d'erreur indique de quel cas il s'agit.
L'écriture dans des signals n'est pas autorisée dans un computed
Un computed doit dériver sa valeur d'autres signals sans effet de bord :
count = signal(1);
total = signal(0);
doubled = computed(() => {
this.total.set(this.count() * 2); // not allowed
return this.count() * 2;
});
Si la valeur dépend uniquement d'autres signals, faites-en elle-même un computed au lieu de la stocker :
Utilisez linkedSignal si la valeur doit aussi être modifiable, ou un effect si l'écriture est un effet de bord du changement.
La même erreur est levée pour les écritures pendant le calcul d'un linkedSignal.
L'écriture dans des signals n'est pas autorisée pendant qu'Angular rend le template
Les expressions de template s'exécutent pendant le rendu ; une méthode appelée depuis le template ne doit donc pas non plus écrire dans un signal :
@Component({
selector: 'app-example',
template: '<p>{{ label() }}</p>',
})
export class Example {
views = signal(0);
label() {
this.views.update((v) => v + 1); // not allowed
return `Viewed ${this.views()} times`;
}
}
Déplacez l'écriture à l'endroit où le changement se produit réellement. L'écriture dans des signals est autorisée dans les event listeners, les lifecycle hooks, les handlers d'output et les effects.
Utiliser untracked
Une écriture enveloppée dans untracked ne lève pas d'erreur. Ne l'utilisez que si l'écriture est intentionnelle et ne peut pas être déplacée, et gardez à l'esprit que les signals lus dans untracked ne sont pas suivis non plus.
Déboguer l'erreur
La stack trace pointe vers l'appel à set ou update. À partir de là, cherchez le computed, le linkedSignal ou l'expression de template qui l'a appelé.