Start / Cheat Sheets

Cheat Sheet

Angular 22 — Kern Cheat Sheet

Stand: · Angular für erfahrene Entwickler

AngularSignalsSignal FormsTypeScript

Dieses Blatt ist zum Danebenlegen gedacht: die Formen und Entscheidungen, die man beim Bauen einer Angular-22-Anwendung ständig braucht und regelmäßig vergisst. Es bringt keine davon bei — dafür sind die Module des Seminars da. Maßgeblich bleibt die offizielle Angular-Dokumentation; der Mehrwert hier liegt in der Auswahl. Was danach kommt — Tests, Barrierefreiheit, Rendering, Sicherheit und Modernisierung — steht auf dem zweiten Blatt Angular 22 — Qualität und Betrieb.

Versionen, Node und TypeScript

AngularNode.jsTypeScript
22.0.x22.22.3, 24.15.0, 26.0.0ab 6.0, unter 6.1
21.x20.19.0, 22.12.0, 24.0.0ab 5.9, unter 6.0
20.2.x20.19.0, 22.12.0, 24.0.0ab 5.8, unter 6.0

Version 22 ist seit dem 03.06.2026 aktiv und bis 06/2027 im Support; 21 und 20 sind im Langzeitsupport, alles darunter bekommt keine Sicherheitspatches mehr. Der Langzeitsupport endet 12 Monate nach der aktiven Phase — ein Projekt bleibt damit höchstens 24 Monate ohne Update im unterstützten Bereich, und ein Sprung über zwei Hauptversionen sind zwei Updates, nicht eines.

Modul: Angular 22 einordnen

Strenge, die gesetzt sein muss

{
  "compilerOptions": { "strict": true, "noUnusedLocals": true },
  "angularCompilerOptions": {
    "strictTemplates": true,
    "typeCheckHostBindings": true
  }
}

strictTemplates findet, was TypeScript allein nicht sieht: eine Eingabe mit dem falschen Typ, ein Feld im Template, das es nicht mehr gibt, einen möglicherweise undefinierten Wert ohne Prüfung, ein Ereignis an einer Methode mit anderer Signatur.

Modul: Workspace, Build und Entwicklungsumgebung

Komponentenverträge: input, output, model

readonly auftrag  = input.required<Auftrag>();
readonly kompakt  = input(false, { transform: booleanAttribute });
readonly nummer   = input('', { alias: 'auftragsnummer' });
readonly geoeffnet = output<string>();
readonly markiert  = model(false);
Dekorator früherSignal-Eingabe heute
@Input() value = 0value = input(0)
Pflicht über Optioninput.required<T>()
Lesen über this.valueLesen über this.value()
Änderung über ngOnChangesÄnderung über computed

model(false) erzeugt zusätzlich die Ausgabe markiertChange; im Template bindet [(markiert)] beide Richtungen. booleanAttribute und numberAttribute liefert Angular mit.

Modul: Komponenten und ihre Verträge

Signals: gespeichert oder abgeleitet

GespeichertAbgeleitet
signal, linkedSignalcomputed
wird gesetztwird berechnet
kann veraltenkann nicht veralten
gehört in den Storegehört neben den Store
private readonly _auftraege = signal<Auftrag[]>([]);
readonly auftraege  = this._auftraege.asReadonly();
readonly treffer    = computed(() =>
  this.auftraege().filter((a) => a.status === this.statusFilter()));
readonly auswahl = linkedSignal<Auftrag[], Auftrag>({
  source: this.treffer,
  computation: (neu, vorher) =>
    neu.find((a) => a.id === vorher?.value.id) ?? neu[0],
});

linkedSignal ist der Fall „Auswahl gehört zu einer Liste, die sich ändern kann”: Ein reines Signal zeigte nach dem Filtern ins Leere, ein computed ließe die Auswahl durch den Nutzer nicht zu.

Bei effect() gilt: Signale vor dem ersten await lesen — danach zählt kein Zugriff mehr als Abhängigkeit. untracked() liest, ohne abhängig zu werden.

Modul: Signals: Zustand modellieren

Signal oder Stream

AufgabeMittel
Aktueller Wert für die Ansichtsignal, computed
Eingabe entprellenObservable mit debounceTime
Mehrere Quellen zusammenführenObservable mit combineLatest
Laufende Anfrage abbrechenObservable oder resource
Abgeleitete Kennzahlcomputed

Die Leitfrage: Wird der Verlauf gebraucht oder nur der aktuelle Wert? Zeitliche Abläufe als Stream modellieren und am Rand in ein Signal überführen — toSignal braucht dabei einen initialValue, sonst liefert es zunächst undefined.

Modul: Zoneless Change Detection und RxJS-Interoperabilität

Kontrollfluss im Template

Variable in @forBedeutung
$indexPosition der aktuellen Zeile
$countAnzahl der Einträge
$first, $lasterste beziehungsweise letzte Zeile
$even, $oddgerader beziehungsweise ungerader Index

track verbindet Datensatz und DOM-Knoten. Ohne stabilen Schlüssel baut Angular Zeilen unnötig neu auf — der Index taugt nur, wenn sich die Reihenfolge nie ändert. @switch vergleicht streng.

Modul: Templates, Kontrollfluss und Wiederverwendung

Wo ein Provider steht

OrtLebensdauerTypischer Fall
bootstrapApplicationAnwendungHttpClient, Konfiguration
Routesolange das Feature aktiv istFeature-Store
Komponenteje EinbaustelleZustand eines Bausteins

Anwendungsweit heißt geteilt, je Komponente heißt getrennt. Ein mehrfach bereitgestellter Dienst erzeugt unbemerkt mehrere Instanzen.

Modul: Dependency Injection

Fehler sind nicht gleich Fehler

ArtBeispielBehandlung
FachfehlerAuftrag bereits abgeschlossenim Modell, sichtbar am Feld
Technische StörungAPI nicht erreichbarzentral, mit Wiederholung
ProgrammfehlerZugriff auf leere AuswahlTest statt Meldung

Modul: Feature-Architektur und Zuständigkeiten

Routing: nachladen und absichern

{ path: 'auswertung',
  loadComponent: () => import('./auswertung/auswertung').then((m) => m.Auswertung) }

export const nurLeitung: CanMatchFn = () => {
  const nutzer = inject(NutzerService);
  return nutzer.istStandortleitung() ? true : inject(Router).createUrlTree(['/']);
};

CanMatchFn verhindert zusätzlich das Nachladen des Bündels, CanActivateFn greift erst danach. Mit withComponentInputBinding wird ein Routenparameter direkt als Eingabe der Komponente gebunden. Ein Guard ist kein Zugriffsschutz — die API prüft noch einmal.

Modul: Routing und Navigation

HTTP: Reaktion nach Fehlerart

LageBeispielReaktion
Netz nicht erreichbarZeitüberschreitungerneut versuchen anbieten
Server meldet 500interner FehlerMeldung, Vorgang abbrechen
Server meldet 409Auftrag gesperrtfachlich am Feld anzeigen
Server meldet 401Sitzung abgelaufenneu anmelden führen

Schreibende Aufrufe nie automatisch wiederholen — sonst wird zweimal angelegt.

Modul: HTTP und typisierter Datenzugriff

resource() und die Werte von status()

readonly detail = resource({
  params: () => ({ id: this.auftragId() }),
  loader: ({ params, abortSignal }) =>
    fetch(`/api/auftraege/${params.id}`, { signal: abortSignal }).then((r) => r.json()),
});
StatusBedeutung
idlekeine gültige Anfrage
loadingParameter haben sich geändert
reloadingreload wurde aufgerufen
resolvederfolgreich abgeschlossen
errorFehler aufgetreten
localWert wurde lokal gesetzt

Ändert sich ein in params gelesenes Signal, bricht Angular die laufende Anfrage ab und startet den loader neu. Liest params kein Signal, lädt die Ressource nie nach.

Modul: Reaktiver Datenabruf mit resource() und httpResource()

Signal Forms

readonly modell = signal({ kennzeichen: '', standort: '', notiz: '' });
readonly formular = form(this.modell, (pfad) => {
  required(pfad.kennzeichen);
  required(pfad.standort);
});

validate(pfad.notiz, ({ value, valueOf }) =>
  valueOf(pfad.dringend) && !value()
    ? { kind: 'notizPflicht', message: 'Grund angeben.' }
    : null);
<input [field]="formular.kennzeichen" />
@if (formular.kennzeichen().touched() && formular.kennzeichen().invalid()) {
  <p role="alert">Kennzeichen fehlt.</p>
}

Serverseitige Befunde über validateHttp zurück ans Feld geben, nicht in eine allgemeine Meldungsbox. Reactive Forms bleiben im Bestand gültig — nur nicht gemischt innerhalb eines Formulars.

Modul: Formulare: Signal Forms und Reactive Forms

Typische Fallen

  • Signal im Template ohne Klammern gelesen — dann steht dort die Funktion, nicht der Wert.
  • Objekt im Signal verändert statt ersetzt — die Gleichheitsprüfung greift, nichts aktualisiert sich. Gleiches gilt für push auf einem Array.
  • Trefferzahl als zweites Signal geführt statt abgeleitet — sie veraltet still.
  • Effekt liest und schreibt dasselbe Signal und läuft im Kreis; oder er ersetzt ein computed und muss die Reihenfolge selbst sicherstellen.
  • Signal nach dem await gelesen — der Effekt läuft nie wieder.
  • Zone.js aus der Konfiguration entfernt, aber als Abhängigkeit installiert geblieben — es kommt über ein Paket zurück.
  • Store steht anwendungsweit, obwohl er zu einem Feature gehört; oder Zustand liegt an der Route und geht beim Verlassen verloren.
  • Nachgeladene Route importiert ihr Ziel zusätzlich statisch — die Grenze wirkt nicht.
  • Antwortformat der API wird direkt als eigenes Modell verwendet und wandert unverändert durch die ganze Anwendung.
  • Fehlermeldung erscheint vor der ersten Berührung, weil touched() nicht geprüft wird.
  • any als Notausgang für einen einzelnen Befund der Template-Prüfung — er breitet sich aus.

Dieses Thema als Schulung für Ihr Team

Dieser Beitrag erklärt das Thema. Damit Ihr Team es danach auch anwendet, gibt es Angular für erfahrene Entwickler als Schulung — an Ihrem eigenen Code, mit den Fragen, die ein Text nicht beantwortet. Sie wählen die Module, wir bauen daraus ein Programm.

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

Als Team-Schulung anfragenZum Seminar Angular für erfahrene Entwickler →