Bereits im ersten Teil haben wir einen Blick auf die grundlegenden Umbaumaßnahmen geworfen, die nötig sind, um ein reaktives Formular in ein Signal-Formular umzuwandeln. Dabei ist uns bereits bei der Implementierung eines Crossfield Validators ein entscheidender Vorteil ins Auge gesprungen: durch die neue Art der Validator-Registrierung und den zugrunde liegenden Signals können wir nun einen typsicheren Validator schreiben, der nur dann ausgeführt wird, wenn ein beteiligtes Feld geändert wird. Aber das ist nicht alles, was die Signal Form besser machen will
Signals
Klingt banal, aber ein Signal als Formular Basis integriert sich nahtlos in die Signal-Welt:
// Formular Daten basierend auf Input-Signal
customerData = input.required<User>({});
customerForm = form(linkedSignal(() => this.customerData));
// Daten bei Änderungen im Formular laden
selectedNewsletterInfo = computed(() => this.loadNewsletterInfo(this.registerForm.newsletters().value()));
constructor() {
// Auf Änderungen im Formular reagieren
effect(() => {
const tacConfirmed = this.registerForm.confirmed().value();
// Do some stuff...
});
}
Bedingte Validatoren
Anstatt bei Änderungen des Formulars Validatoren nachträglich hinzuzufügen oder zu entfernen, erlauben uns die Signal Form direkt bei der Registrierung Bedingungen zu deklarieren.
registerForm = form(this.registerFormData, (schema) => {
required(schema.passwordRepeat, {
when: (context) => !!context.valueOf(schema.password)
});
(Validator ist nur aktiv, wenn das Feld „password“ einen Wert hat)
Disabled Fields
Bereits im letzten Artikel habe ich angemerkt, dass mir die Trennung von Formular-Struktur und Validatoren nicht gefällt. Die Schema-Funktion bietet dafür aber, analog zu den Validatoren, auch die Möglichkeit Feld-Status zu managen und auch hier optional mit Bedingungen
registerForm = form(this.registerFormData, (schema) => {
disabled(schema.newslettersB, (context) => {
return !context.valueOf(schema.newsletter)
})
Submit
Die Signal Form kommen mit einer eigenen Submit-Methode, die es uns erlaubt Server-Fehler in unserem Form-Tree unterzubringen. Dazu müssen wir in einem Fehler-Fall lediglich entsprechende Fehler zurückmelden anstatt undefined
submit(this.registerForm, async () => {
// do some server stuff
return [{
fieldTree: this.registerForm.mail,
kind: 'server',
message: 'I Dont like this email'
}];
})
Custom Input Components
By By NG_VALUE_ACCESSOR und Boilerplate Coding für eigene Formular-Komponenten. Jetzt reicht ein einfaches Interface mit einem value-Signal.
export class Test implements FormValueControl<Userdata>{
readonly value = model.required<Userdata>();
readonly disabled = input(false);
// optional stehen hier weitere input-Signals zur Verfügung, touched,dirty,invalid etc.
}
Fazit
Alles, was die Signal Form kann, lässt sich auch mit einer Reactive Form realisieren. Also kein Grund Nachtschichten einzulegen, um eine Umstellung in bestehenden Projekten zu forcieren. Angulars Weg hin zu Signals als Best-Practice ist aber unumstritten, sollte also für neue Bereiche ganz klar im Fokus stehen. Stand Angular 21 sind die Signal Forms als experimental gekennzeichnet, also noch nichts für kritische, laufende Anwendungen. Hoffen wir auf ein baldiges Final-Release.





