Start / Seminare / Angular für erfahrene Entwickler

Modul

Signals: Zustand modellieren

Modul 5 von 22 aus dem Seminar Angular für erfahrene Entwickler

5 Kapitel in diesem Modul-Video · Laufzeit

Für Teams

Die Videos zeigen, wie es geht. Die Schulung sorgt dafür, dass Ihr Team es danach tut.

Ein Video kann niemanden fragen, warum es ausgerechnet in Ihrem Repository nicht funktioniert. Es kann kein Team auf eine gemeinsame Konvention bringen. Und es setzt sich niemand freiwillig drei Tage hin. In der Schulung sind am Ende alle auf demselben Stand, gearbeitet wurde am eigenen Code, und die offenen Fragen sind entschieden — in ein paar Tagen statt irgendwann nebenbei.

Vorgespräch am Telefon · Programm nach Maß · ab 1 Tag (8 Unterrichtseinheiten) · Teilnahmezertifikat

Schulung anfragen So läuft eine Schulung ab

Vertonung mit synthetischer Stimme · Inhalte redaktionell verantwortet · © 2026 HECKER CONSULTING, alle Rechte vorbehalten

Transkript

Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.

Signals — Zustand modellieren

0:00 Signals sind die vielleicht wichtigste Neuerung der letzten Angular-Jahre, und sie werden regelmäßig falsch eingeordnet. Ein Signal ist kein Ereignis. Es ist auch kein Stream. Es ist schlicht ein Wert, der Bescheid sagt, wenn er sich geändert hat. Klingt unspektakulär — und verändert trotzdem, wie man über Zustand nachdenkt.

0:19 In diesem Modul geht es um die drei Arten von Zustand, die Sie sauber auseinanderhalten sollten, und um die eine Funktion, die man deutlich seltener braucht, als man zuerst denkt.

Reaktivität und Anwendungsstruktur

0:30 Der zweite Tag hat ein Thema: Wo wohnt der Zustand, und wer darf ihn ändern? Vormittags klären wir, wie Angular Zustand und Änderungen behandelt — mit Signals und ohne Zone.js. Nachmittags geht es um Struktur: Dependency Injection und die Frage, welcher Teil Ihrer Anwendung eigentlich wofür zuständig ist.

signal() als Baustein des Zustands

0:50 Fangen wir beim kleinsten Baustein an. Was ein Signal ist, ist schnell erzählt — interessanter ist, was es Ihnen abnimmt. Ein Signal ist eine Hülle um einen Wert. Sie lesen ihn durch Aufruf, Sie setzen ihn neu oder leiten den neuen aus dem alten ab. Das Besondere: Wer das Signal liest, meldet sich damit automatisch an. Ändert sich der Wert, wird er erneut ausgewertet — ohne Abonnement, ohne Abmelden.

1:15 Denken Sie an eine Anzeigetafel am Bahnsteig. Sie schauen hin und sehen den aktuellen Stand; ändert sich etwas, ändert sich die Tafel. Sie müssen sich nirgends registrieren, und Sie müssen sich auch nirgends abmelden, wenn Sie weggehen. Zwei Muster sind hier wichtiger als die Syntax. Erstens die Trennung von Schreiben und Lesen: Das Signal ist privat, nach außen geht eine Nur-Lese-Ansicht.

1:39 Damit ist im Code sichtbar, wer den Zustand ändern darf — nämlich der Store und sonst niemand. Zweitens die Feinheit des Zuschnitts: Filter und Liste sind getrennte Signals, nicht ein Objekt mit beidem darin. Das klingt nach mehr Aufwand und zahlt sich später aus, wenn sich nur der Filter ändert und die Liste nicht neu betrachtet werden muss.

1:59 Vier Punkte, und der erste ist der, der die Arbeit abnimmt: Wer das Signal liest, wird bei Änderung selbsttätig neu ausgewertet. Sie schreiben kein Abonnement und vergessen keines zu beenden. Das Template meldet sich von allein an. Der dritte Punkt ist der, den ich beim Lesen von Code am meisten schätze: Die Abhängigkeiten stehen im Code und nicht in einer Aufrufkette.

2:21 Man sieht, was von was abhängt, statt es zu rekonstruieren. Und der vierte ist der Leistungsaspekt: Feingranular gedacht ändert sich nur, was sich wirklich geändert hat. Der erste Punkt ist der mit Abstand häufigste Fehler beim Einstieg: Ein Objekt im Signal wird verändert statt ersetzt. Angular vergleicht standardmäßig auf Identität — dieselbe Referenz heißt „nichts passiert", auch wenn innen alles anders ist.

2:45 Der zweite ist ein Tippfehler mit Folgen: Das Signal wird im Template ohne Klammern gelesen und liefert dann die Funktion selbst. Das sieht in der Anzeige merkwürdig aus und ist schnell gefunden. Und der dritte ist eine Erwartung, die nicht erfüllt wird: Ein Nur-Lese-Signal schützt nicht vor tiefer Änderung seines Inhalts.

Abgeleiteten Zustand mit computed()

3:04 Jetzt zur zweiten Art von Zustand — und zu der Regel, die aus meiner Sicht die meisten Fehler verhindert, die ich in Anwendungen sehe. Eine Ableitung berechnet ihren Wert aus anderen Signals. Sie ist nicht beschreibbar, sie wird erst bei Bedarf berechnet und merkt sich das Ergebnis. Der spannende Teil ist die Abhängigkeitsermittlung: Angular zählt nur die Signals, die tatsächlich gelesen wurden.

3:28 Steht ein Zugriff hinter einer Bedingung, kann sich die Abhängigkeit von Durchlauf zu Durchlauf ändern — und Angular kommt damit zurecht. Die Regel dahinter ist simpel: Was sich berechnen lässt, wird nicht gespeichert. Worauf es hier ankommt, ist eine Abwesenheit. Nirgends steht ein Feld „anzahl", das jemand setzen müsste.

3:47 Die Trefferliste leitet sich aus Bestand und Filter ab, die Anzahl leitet sich aus der Trefferliste ab. Damit gibt es keinen Zustand, der veralten könnte. Die typische Alternative kennen Sie: ein Feld für die Anzahl, das an drei Stellen aktualisiert wird — und an einer vierten, die jemand später hinzufügt, eben nicht. Genau das ist der Fehler, den diese Struktur unmöglich macht.

4:11 Diese Gegenüberstellung ist der Kern des ganzen Moduls. Links das Gespeicherte: Es wird gesetzt, und es kann veralten. Rechts das Abgeleitete: Es wird berechnet, und es kann per Konstruktion nicht veralten. Wenn Sie in einer Anwendung nach Fehlern suchen, die sich als „hier steht eine alte Zahl" äußern, dann finden Sie sie immer links — und die Lösung besteht fast immer darin, den Wert nach rechts zu verschieben.

4:35 Nehmen Sie diese Einteilung als Prüfschema mit: Für jeden Wert in Ihrem Zustand die Frage, in welche Spalte er gehört. Der erste Punkt ist der, der in jeder gewachsenen Anwendung steckt: Die Trefferzahl wird zusätzlich als Signal geführt und läuft irgendwann auseinander. Der zweite ist heimtückischer: Eine Ableitung schreibt nebenbei in ein anderes Signal.

4:56 Damit ist sie keine Ableitung mehr, sondern ein Effekt mit Tarnkappe — und die Reihenfolge, in der alles ausgewertet wird, wird plötzlich wichtig. Der dritte betrifft die Leistung: Eine teure Berechnung steckt in einer Ableitung, und niemand misst sie, weil sie so unscheinbar aussieht.

linkedSignal() für zurücksetzbaren Zustand

5:12 Und jetzt die dritte Art, die den beiden anderen lange gefehlt hat. Sie löst ein Problem, das Sie garantiert kennen, auch wenn Sie es bisher anders gelöst haben. Stellen Sie sich eine Auswahl in einer Liste vor. Sie soll wählbar sein — also schreibbar. Sie soll aber auch mitbekommen, wenn sich die Liste ändert. Ein einfaches Signal kann das Erste, eine Ableitung das Zweite, und beides zusammen konnte man lange nur von Hand bauen.

5:38 Ein gekoppeltes Signal kann beides: Es berechnet sich wie eine Ableitung, lässt sich aber schreiben. Ändert sich die Quelle, wird neu berechnet und eine zwischenzeitliche Änderung verworfen. Die ausführliche Form kennt zusätzlich den vorherigen Wert. Der entscheidende Ausdruck steht in der Mitte: Suche den vorherigen Eintrag anhand seiner Kennung in der neuen Liste. Ist er noch da, bleib bei ihm. Ist er weg, nimm den ersten.

6:04 Ohne diese Suche springt die Auswahl bei jedem Filterwechsel zurück auf den ersten Treffer — was für den Benutzer aussieht wie ein Fehler. Mit ihr bleibt der Auftrag ausgewählt, solange er im Filter enthalten ist, und weicht sonst sauber aus. Das ist genau das Verhalten, das man erwartet und das man sonst von Hand nachbauen müsste.

6:23 Diese vier Zeilen beschreiben eine Situation, die in praktisch jeder Anwendung vorkommt: eine Auswahl, die zu einer veränderlichen Liste gehört. Filter, Suche, Paginierung — überall dasselbe Muster. Die beiden Alternativen versagen an je einer Stelle. Ein reines Signal weiß nichts von der Liste und zeigt irgendwann auf einen Eintrag, den es nicht mehr gibt.

6:45 Eine Ableitung wüsste von der Liste, ließe aber die Auswahl durch den Benutzer nicht zu. Deshalb gibt es die dritte Form — nicht als Feinheit, sondern weil die Lücke real war. Der erste Punkt betrifft die Kurzform: Sie wird benutzt, obwohl der vorherige Wert erhalten bleiben soll. Dann verwirft sie ihn bei jeder Änderung der Quelle, und man wundert sich.

7:06 Der zweite geht in die andere Richtung — ein gekoppeltes Signal ersetzt eine Ableitung, die nie geschrieben wird. Das ist unnötige Beweglichkeit; eine Ableitung wäre klarer gewesen. Und der dritte ist einer, den man erst im Betrieb merkt: Die Quelle ändert sich häufiger als gedacht und verwirft Eingaben, an denen der Benutzer gerade arbeitet.

effect() sparsam einsetzen

7:26 Bleibt die vierte Funktion — und die einzige in diesem Modul, zu der ich Ihnen vor allem sagen möchte, wann Sie sie nicht brauchen. Ein Effekt läuft, wenn sich gelesene Signals geändert haben. Er ist der Ausgang zur nicht reaktiven Welt — für Dinge, die außerhalb Ihrer Signal-Welt passieren müssen. Er ist ausdrücklich kein Ersatz für eine Ableitung. Und er hat eine Eigenschaft, die man kennen muss: Nach einem „await" ist der reaktive Kontext verloren.

7:54 Signals, die Sie danach lesen, zählen nicht mehr als Abhängigkeit. Wer das nicht weiß, baut einen Effekt, der genau einmal läuft und danach nie wieder — ohne jede Fehlermeldung. Hier stehen beide Fallen nebeneinander. Oben die zeitliche: Das Signal wird vor dem „await" gelesen, und genau darauf kommt es an. Danach wäre es zu spät.

8:14 Unten die absichtliche Ausnahme: Ein Signal soll gelesen, aber nicht abonniert werden — der Wert soll mitgeschickt werden, ohne den Effekt auszulösen. Dafür gibt es eine eigene Funktion. Beide Muster sehen unscheinbar aus und sind der Unterschied zwischen einem Effekt, der arbeitet, und einem, der nach dem ersten Lauf verstummt.

8:35 Vier Fallen, und die erste ist die gefährlichste: Ein Effekt schreibt ein Signal, das er selbst liest, und läuft im Kreis. Die zweite ist die häufigste: Ein Effekt ersetzt eine Ableitung — dann muss er die Reihenfolge selbst sicherstellen, und das wird schnell brüchig. Die dritte ist die, die niemand meldet: Ein Signal wird nach dem „await" gelesen, und der Effekt läuft nie wieder.

8:57 Und die vierte ist die unaufgeräumte: Was der Effekt registriert hat, wird beim Beenden nicht wieder abgemeldet.

Übung

9:04 Bringen wir die drei Arten zusammen — an einem Fehler, den es bei Falkenhorst wirklich gab. Die Auftragsübersicht filtert nach Status und markiert einen Auftrag als ausgewählt. In einer früheren Fassung verschwand die Auswahl beim Filterwechsel — ärgerlich, aber harmlos. Schlimmer war die zweite Variante: Sie zeigte auf einen Auftrag, der gar nicht mehr in der Liste stand.

9:26 Die Detailansicht daneben zeigte also etwas anderes als die Markierung in der Liste. Solche Fehler werden selten gemeldet, weil niemand sie richtig beschreiben kann. Man sagt dann: Die Anwendung verhält sich manchmal komisch. Das Lernziel ist die Unterscheidung selbst: gespeichert, abgeleitet, gekoppelt — und die Wahl begründen können.

9:46 Das Erfolgskriterium hat drei Teile, und der letzte ist der entscheidende: Kein Wert wird an zwei Stellen geführt. Das ist eine Behauptung, die sich prüfen lässt — gehen Sie Ihre Felder durch und fragen Sie bei jedem, ob es einen zweiten Ort gibt, an dem dieselbe Information steht. Wer früh fertig ist, ersetzt einen bewusst falsch gesetzten Effekt durch eine Ableitung und belegt den Unterschied an einem echten Fehler.

10:10 Der erste Schritt ist der, den man am liebsten überspringt und der die eigentliche Arbeit ist: alle Zustandswerte auflisten und je Zeile die Art bestimmen. Machen Sie das schriftlich. Danach sind die Schritte zwei bis vier fast mechanisch — gespeichert als Signal mit Nur-Lese-Ansicht, Kennzahlen als Ableitung, Auswahl gekoppelt.

10:29 Und der fünfte ist die Probe: Filter wechseln und schauen, worauf die Auswahl danach zeigt. Wenn sie sinnvoll ausweicht, stimmt die Modellierung. Wenn sie springt oder ins Leere zeigt, stimmt sie nicht. Die drei Fallen entsprechen genau den drei Arten. Die Trefferzahl wird gesetzt statt abgeleitet und veraltet still — der Klassiker.

10:49 Die Auswahl bleibt ein einfaches Signal und zeigt ins Leere. Und ein Effekt hält zwei Signals von Hand synchron, was nichts anderes ist als eine Ableitung mit mehr Zeilen und mehr Risiko. Im nächsten Modul schauen wir uns an, wie Angular überhaupt merkt, dass sich etwas geändert hat — und warum das ohne Zone.js anders funktioniert als früher.

Dieses Modul als Schulung für Ihr Team

Das Video zeigt den Stoff. In der Schulung arbeitet Ihr Team damit — an Ihrem eigenen Code, mit Übungen und mit den Fragen, die ein Video nicht beantwortet. Sie wählen die Module aus Angular für erfahrene Entwickler, wir bauen daraus ein Programm.

6 Tage·ab 900 EUR netto pro Tag (bis 3 Teilnehmende) ·Termin nach Vereinbarung

Als Team-Schulung anfragenWie eine Schulung abläuft →