Zurück zu Blogs
Web Entwicklung

Angular Signal Forms: Wie Enterprise Applikationen migrieren sollen

Signal Forms bringen Angular einen entscheidenden Schritt weiter: Formulare werden Teil des Signal-basierten Reaktivitätsmodells und verlieren ihren bisherigen Sonderstatus. Der Artikel zeigt kompakt, wo die Vorteile liegen und vor allem, wie bestehende Enterprise-Anwendungen schrittweise und ohne großen Umbruch migriert werden können.

Daniel Kappacher

Daniel Kappacher

Angular Signal Forms: Wie Enterprise Applikationen migrieren sollen

Angular baut sein Reaktivitätsmodell seit einiger Zeit konsequent um. Signals sind inzwischen die neue Grundlage. State, Ableitungen und Effects folgen einer deutlich klareren Logik als früher. Was dabei lange nicht zusammengepasst hat, waren Formulare. Denn während der Rest der Anwendung zunehmend signal-basiert wird, hängen diese noch an Reactive Forms.

Zum einen ist dabei der RxJS-basierende Aufbau ein architektonischer Bruch, und zum anderen bringen Reactive Forms auch unabhängig von der Signals Migration schnell eine gewisse Komplexität und Unberechenbarkeit in die Applikation. Viel verteilter Code mit verschachtelten FormGroup Models und Definitionen, Seiteneffekte mit valueChanges Subscriptions und Change Detection Probleme bei Formularen, die sich über mehrere Komponenten verstreuen.

Mit den neuen Signal Forms bietet Angular jetzt einen Formularansatz, der voll auf Signals basiert und so einiges an Boilerplate Code verliert.

Signal Forms Basics

Der grundlegende Unterschied ist schnell verstanden. Statt mit FormGroup und FormControl zu starten, definiert man zuerst ein Model, welches die zentrale Quelle für den gesamten Form-State ist.

const profile = signal({
  username: '',
  email: '',
  newsletter: false,
});

const profileForm = form(profile, (path) => {
  required(path.username);
  required(path.email);
  email(path.email);
});

Das von der form() Funktion zurückgegebene Objekt vom Typ FieldTree ermöglicht den Zugriff auf die jeweiligen FieldState Objekte. Somit können Formularwerte und Zustände einzelner Felder ganz einfach als Signals ausgelesen und weiterverarbeitet werden.

const username = profileForm.username().value();
const isUsernameDirty = profileForm.username().dirty();
const isUsernameValid = profileForm.username().valid();

Im Template bindet man mithilfe des importierten formField Directives direkt auf die FieldState Properties:

<input [formField]="profileForm.username" />

Der große Unterschied zeigt sich im Verhalten. Änderungen laufen synchron durch das System, ohne Subscriptions oder valueChanges. State und Change Detection werden somit berechenbarer.

Die neuen Signal Forms bieten noch zahlreiche weitere Features out of the box, für die es bis jetzt oft eine Custom Logik brauchte. Dazu zählen unter anderem:

  • Bedingtes disabled setzen von Formularfeldern mit der disabled() Funktion
  • Debouncing von Eingaben – ohne RxJS – mit der debounce() Funktion
  • Bedingte Validierungen mit der applyWhenValue() und applyWhen() Funktion
  • Handling von Metadaten mit createMetadataKey()
  • Custom-Form-Komponenten mit FormValueControl Interface. Kein ControlValueAccessor mehr notwendig.

Realistische Einschätzung

Für neue Projekte ist die Richtung ziemlich klar. Auch wenn das Feature noch als experimentell markiert ist, haben andere Features gezeigt, dass sich Breaking Changes in neuen Angular Releases in Grenzen halten. Zumindest ist es anzunehmen, dass eine Migration von Reactive Forms mehr Kopfschmerzen bereiten würde, als ein paar kleinere Anpassungen an der Signal Forms API in zukünftigen Versionen.

In bestehenden Anwendungen sieht das anders aus. Formulare gehören dort oft zu den komplexesten Teilen der Anwendung. Validierungen, Abhängigkeiten zwischen Feldern, API-Integration oder auch historisch gewachsene Logik machen einen einfachen Austausch schwierig.

Deshalb ist die zentrale Frage nicht, ob Signal Forms Reactive Forms ersetzen, sondern wie man den Übergang sinnvoll gestaltet.

Signal Forms Interop

Statt eines harten Umstiegs gibt es seit Angular 21.2 zwei gezielte Integrationspunkte, mit denen sich beide Ansätze kombinieren lassen und somit eine schrittweise Migration von komplexeren Formularen ermöglichen.

SignalFormControl

Mit SignalFormControl können einzelne Controls innerhalb eines bestehenden Reactive Forms modernisiert werden, ohne das gesamte Formular umzubauen.

ageControl = new SignalFormControl(0, (path) => {
  required(path);
});

form = this.fb.group({
  name: [''],
  age: this.ageControl,
});

SignalFormControl implementiert AbstractControl und verhält sich somit nach außen hin wie ein normales FormControl. Das bestehende Formular bleibt stabil, inklusive Validierung und Status.

Der Vorteil zeigt sich eher intern. Man kann auf das zugrunde liegende Signal zugreifen und es direkt weiterverwenden:

const isAdult = computed(() => {
  return this.ageControl.sourceValue() >= 18;
});

So lässt sich Logik, die bisher in valueChanges hing, schrittweise in eine signal-basierte Struktur überführen.

compatForm

Der zweite Einstiegspunkt geht in die andere Richtung. Hier baut man ein Signal Form auf, integriert aber weiterhin bestehende Reactive Forms.

const profileModel = signal({
  username: '',
  details: this.reactiveForm,
});

const profileForm = compatForm(profileModel, (path) => {
  required(path.username);
});

Im Template werden beide Ansätze kombiniert:

<input [formField]="profileForm.username" />

<div [formGroup]="reactiveForm">
  <input formControlName="email" />
  <input formControlName="phone" />
</div>

Das erlaubt es, neue Teile bereits signal-basiert umzusetzen, während bestehende Strukturen unverändert bleiben.

Was bedeutet das konkret für Enterprise Anwendungen?

In der Praxis ergibt sich folgende mögliche Migrationsstrategie:

  • Neue Features lassen sich direkt mit Signal Forms umsetzen. Das reduziert Komplexität und ist einheitlich mit dem restlichen signal-basierten Ansatz.
  • Große Formulare, die aufgrund hoher Komplexität oder vielen Seiteneffekten die Wartbarkeit erschweren, können mit den beiden oben genannten Interop Funktionen entschärft werden. Ohne großen Migrationsaufwand und mit direkt spürbarem Impact.
  • Geplante Change Requests oder Refactorings von bestehenden Features mit Reactive Forms bieten eine gute Möglichkeit, den Umstieg auf Signal Forms zu wagen.
  • Für Reactive Forms, die stabil funktionieren und wartbar bleiben, kann vorerst abgewartet werden bis die neuen Forms stable werden und eventuell von Angular automatisierte Migrations-Skripte als Unterstützung angeboten werden.

Zusammenfassung

Signal Forms zeigen, in welche Richtung sich Angular entwickelt. Formulare werden Teil des gleichen reaktiven Systems und lassen sich deutlich konsistenter modellieren als bisher. Gerade die Möglichkeiten bei Validierung und Struktur sind flexibler und besser wiederverwendbar, ohne dass viel zusätzliche Logik nötig ist.

Auch wenn das Feature noch experimentell ist, lohnt sich ein Einstieg über einzelne Features. So bekommt man schnell ein Gefühl dafür, wo der Ansatz im eigenen Projekt echten Mehrwert bringt.

Share this post
Daniel Kappacher

Daniel Kappacher