This document describes the architecture of Angular's Forms system, which provides two approaches for handling user input: Template-driven forms and Reactive forms. The Forms system manages form controls, validation, state tracking, and synchronization between the DOM and the application model.
This page covers:
AbstractControl, FormControl, FormGroup, FormArray)ControlValueAccessor bridge patternFor detailed guides on specific implementations, see Template-Driven Forms and Reactive Forms and Signal Forms.
The Forms system is built on a hierarchy of classes that represent form inputs and their organizational structure. All controls derive from AbstractControl.
Sources: packages/forms/src/model/abstract_model.ts25-109 packages/forms/src/model/form_group.ts188-194 packages/forms/src/model/form_array.ts122-125
AbstractControl tracks the value, validity status, and user interaction state (pristine/touched) of a form element.
| Status | Constant | Description |
|---|---|---|
| VALID | VALID | No errors exist in the input value packages/forms/src/model/abstract_model.ts44 |
| INVALID | INVALID | An error exists in the input value packages/forms/src/model/abstract_model.ts51 |
| PENDING | PENDING | Async validation is occurring packages/forms/src/model/abstract_model.ts60 |
| DISABLED | DISABLED | Control is exempt from validity/value calculations packages/forms/src/model/abstract_model.ts69 |
Sources: packages/forms/src/model/abstract_model.ts44-86 goldens/public-api/forms/index.api.md34-43
The ControlValueAccessor interface acts as a bridge between Angular's FormControl instances and built-in DOM elements. It abstracts the underlying DOM interaction, allowing the forms API to work with any type of input.
Classes implementing ControlValueAccessor must provide the following methods:
writeValue(obj: any): Writes a new value from the form model to the view (DOM) packages/forms/test/reactive_integration_spec.ts127registerOnChange(fn: any): Registers a callback function that is called when the value changes in the view packages/forms/test/reactive_integration_spec.ts128registerOnTouched(fn: any): Registers a callback function that is called by the forms API on HTTP/DOM blur events packages/forms/test/reactive_integration_spec.ts129Sources: adev/src/content/guide/forms/overview.md66 packages/forms/test/reactive_integration_spec.ts114-132
Angular supports two data flow models: Synchronous (Reactive) and Asynchronous (Template-driven).
In reactive forms, the component class is the source of truth.
FormControl.setValue().FormControl notifies the ControlValueAccessor.ControlValueAccessor updates the DOM element.<input>.input event.ControlValueAccessor catches the event and calls the registered onChange callback.NgModel directive updates the internal FormControl instance.FormControl emits a value through the valueChanges observable.Sources: adev/src/content/guide/forms/overview.md35 adev/src/content/guide/forms/reactive-forms.md8-10 adev/src/content/guide/forms/overview.md91-95
Validation is handled by functions that take an AbstractControl and return ValidationErrors or null.
FormControl adev/src/content/guide/forms/form-validation.md49Promise or Observable. Passed as the third argument adev/src/content/guide/forms/form-validation.md50 Angular only runs async validators if all sync validators pass adev/src/content/guide/forms/form-validation.md52Sources: adev/src/content/guide/forms/form-validation.md60-67 packages/forms/src/model/abstract_model.ts25
The forms system uses RxJS observables to track state changes across the AbstractControl hierarchy.
The events property on AbstractControl emits specific event types packages/forms/src/model/abstract_model.ts89-100:
ValueChangeEvent: Fired when the value changes packages/forms/src/model/abstract_model.ts109StatusChangeEvent: Fired when validation status changes packages/forms/src/model/abstract_model.ts156PristineChangeEvent: Fired when the pristine state toggles packages/forms/src/model/abstract_model.ts124TouchedChangeEvent: Fired when the touched state changes packages/forms/src/model/abstract_model.ts140valueChanges: Emits the latest value goldens/public-api/forms/index.api.md108statusChanges: Emits the latest FormControlStatus goldens/public-api/forms/index.api.md96Sources: packages/forms/src/model/abstract_model.ts89-188 goldens/public-api/forms/index.api.md95-108
Refresh this wiki