W10.1 hat den Workspace gebaut, W10.2 schneidet ihn nach Fachgebieten. Diese Lektion fragt, wo innerhalb eines Fachgebiets der Zustand wohnt: die Liste der Kontakte, der gewählte Kontakt, der Filter, der Ladezustand. Wir schreiben dafür einen Store mit NgRx Signal Store in kontakte-data-access, binden ihn an die Feature-Bibliothek und testen ihn.
Vorausgesetzt werden W9 (Signals, HttpClient, Tests) und der Workspace aus W10.1.
Stand der Prüfung. Ausgeführt (Node 24.22.3, Nx 24.0.6, Angular 22.2,
@ngrx/signals22.0.1, Vitest 4.1.12, Wegwerf-Workspace außerhalb des Repositorys, der aus W10.1 hervorging): Store, Dienst, Komponente und Tests unten;nx test kontakte-data-accessExit 0 mit 6 Tests,nx run-many -t lint test buildExit 0 für sechs Projekte. Gelesen: Der Abruf von ngrx.io lieferte uns nur das Gerüst der Seiten. Die Aussagen übersignalStore,rxMethod,providedIn,protectedState,setAllEntitiesund die Testseite stammen aus Auszügen der ngrx.io-Seiten, die ein Dokumentationsdienst lieferte (Seiten „SignalStore“, „Entity Management“, „Testing“); die Seiten selbst haben wir nicht im Browser gelesen. Offen (nicht gelesen):signalState,signalStoreFeature,withHooks, das Ereignis-API, Stabilitätsvermerke („Preview“ oder ähnlich) und was die Seite zur Wahl zwischen Store und Dienst sagt. Nicht ausgeführt: ein Dienst mit Signals im Abschnitt „Wo Zustand wohnt“ (nur Skizze), Redux DevTools und andere Erweiterungen.
Wo Zustand wohnt
Zustand hat einen Ort, und der Ort bestimmt, wer ihn ändern darf und wann er verschwindet.
| Ort | Beispiel in der Kladde | Lebt, bis … |
|---|---|---|
Komponente (signal) |
ob ein Aufklappbereich offen ist | die Komponente zerstört wird |
| Dienst mit Signals | der gewählte Kontakt für zwei Komponenten | der Injektor des Dienstes endet |
| Store (Signal Store) | Liste, Auswahl, Filter, Ladezustand eines Fachgebiets | der Injektor des Stores endet |
| Server | die Kontakte selbst | sie gelöscht werden |
Die Regel dieses Kurses: so nah an der Verwendung wie möglich. Ein Signal in der Komponente reicht, solange nur sie den Wert braucht. Brauchen ihn zwei, zieht er in einen Dienst. Ein Store lohnt, wenn mehrere Teile zusammengehörenden Zustand ändern und Regeln dafür gelten (Filter und Liste, Laden und Fehler), und ein Test diese Regeln ohne Oberfläche prüfen soll. Ein Dienst mit Signals ist der Standardweg und kommt ohne Zusatzpaket aus (Skizze, nicht ausgeführt):
@Service()
export class AuswahlDienst {
readonly gewaehlt = signal<number | null>(null);
waehle(id: number | null): void {
this.gewaehlt.set(id);
}
}
Der Store bringt gegenüber diesem Dienst eine Form: Zustand, abgeleitete Werte und Methoden stehen an festen Stellen, und der Zustand ist von außen nicht beschreibbar (siehe unten). Ob ein Team diese Form braucht, ist Geschmack und Teamgröße; die Seite von NgRx zur Wahl haben wir nicht gelesen.
Zustand des Servers ist etwas anderes: Die Kontakte gehören dem Server, der Client hält eine Kopie. resource und httpResource (W9 0202) modellieren genau das: eine Anfrage, ihr Ergebnis, Laden und Fehler. Im Store liegt, was der Client entscheidet (Filter, Auswahl), und eine geladene Seite, die er verändern und weiterreichen will. Beides nebeneinander ist kein Widerspruch; wie weit man httpResource und Store mischt, haben wir nicht erprobt.