The Forms System provides infrastructure for creating and managing forms in Angular applications. It handles user input, validation, state tracking, and synchronization between TypeScript models and HTML form elements. Angular offers three primary approaches:
This document covers the high-level architecture and how these systems relate. For deep dives, see the child pages.
The forms system is built on a shared foundation of control abstractions and value accessors that bridge the gap between the framework and the DOM.
Sources: packages/forms/src/model/abstract_model.ts25-109 packages/forms/signals/src/api/structure.ts102-152 packages/core/src/render3/instructions/control.ts38-86
In traditional forms, AbstractControl is the base class packages/forms/src/model/abstract_model.ts93-100 It tracks:
VALID, INVALID, PENDING, or DISABLED packages/forms/src/model/abstract_model.ts44-86pristine vs dirty and touched vs untouched packages/forms/src/model/abstract_model.ts119-147ControlEvent objects including ValueChangeEvent and StatusChangeEvent packages/forms/src/model/abstract_model.ts109-163For details on the control hierarchy and rendering model, see Forms Architecture.
The new signal-based forms introduce FieldState, which exposes form data as signals rather than Observables packages/forms/signals/src/api/types.ts138-151
value: A WritableSignal<T> representing the current data packages/forms/signals/src/field/node.ts163-165valid/invalid: Computed signals derived from validation logic packages/forms/signals/src/field/node.ts187-193fieldTree: A proxy object that allows navigating the form structure using standard property access (e.g., myForm.address.city()) packages/forms/signals/src/field/node.ts88-91| Feature | Template-Driven | Reactive | Signal Forms |
|---|---|---|---|
| Model Creation | Implicit (Directives) | Explicit (TypeScript) | Explicit (Signals) |
| Data Flow | Asynchronous | Synchronous | Reactive (Signals) |
| Validation | Directives | Functions | Schema/Logic Nodes |
| Type Safety | Low | Improved (v14+) | High (Inferred) |
Best for simple forms where logic is minimal. It relies on directives like NgModel and NgForm.
For details, see Template-Driven Forms.
Reactive Forms provide a robust, immutable way to manage form state using FormControl, FormGroup, and FormArray.
Signal Forms (Experimental) represent the future of Angular forms, integrating directly with the Signals reactivity model. They use a form() function to wrap model data packages/forms/signals/src/api/structure.ts102-152 and support advanced features like debounce and disabled logic bound directly to the schema packages/forms/signals/src/api/types.ts97-105
A Compat Layer exists to allow Signal Forms to interoperate with traditional AbstractControl based components goldens/public-api/forms/signals/compat/index.api.md18-58
For details, see Reactive Forms and Signal Forms.
The forms system integrates with the Angular renderer through special instructions like ɵɵcontrolCreate and ɵɵcontrolUpdate packages/core/src/render3/instructions/control.ts38-68 These instructions manage the lifecycle of form directives and ensure that ControlValueAccessor instances are correctly initialized and updated during change detection cycles packages/core/src/render3/instructions/control.ts42-59
Sources: packages/core/src/render3/instructions/control.ts1-86 packages/forms/src/model/abstract_model.ts1-100
Validation in the new signal system is handled via a Schema that defines rules like required, email, or pattern goldens/public-api/forms/signals/index.api.md117-129 It supports:
Resource for asynchronous checks goldens/public-api/forms/signals/index.api.md47-54Sources: packages/forms/signals/src/api/types.ts140-185 packages/forms/signals/src/field/node.ts75-105