This blog describes the concept and implementation of Angular form control.
Generally speaking, there are two ways to create a reusable component in Angular: as a regular
Component, or as a value accessor. A value accessor is a
Component that also implements the
ControlValueAccessor interface. A value accessor wraps a DOM element and can be bound to a
FormControl class intance, called a form control, that tracks the value and the validation status of the DOM element. It can be used alone or in a form.
NgModel directives to create a 2-way binding of a form control to a DOM element via the corresponding value accessor. It means the following:
any values written to the
FormControlinstance programmatically will be written to the DOM element (model -> view). Conversely, any values written to the DOM element through user input will be reflected in the FormControl instance (view -> model).
ControlValueAccessor interface acts as a bridge between a forms control and a DOM element.
<input type="text" [formControl]="myControl"> bind the
<input> element to a property of
myContorl - it is a
FormControl instance created in the component. The value accessor for the
<input type="text"> element is the
FormControlDirective is designed to be used as a standalone control.
FormControlName is designed to be used with a parent FormGroupDirective (selector: [formGroup]).
NgModel is used in template-driven forms – not recommended for its testing difficulties and synchronous API.
2 The Value Accessor
FormControlDirective directive, and the other two directives too, uses the
NG_VALUE_ACCESSOR injector token to get a
ControlValueAccessor instance. A
ControlValueAccessor interface wraps around a form element and has four methods:
writeValue: to write a value to a native element.
registerOnChange: to register a callback on a change in the UI: a value change of the element.
registerOnTouch: to register a callback when the element receives a blur event.
setDisabledState: to disable or enable the element.
Angular implements default value accessors for Dom element like
input(text, number, checkbox, radio and range),
textarea has the following code (changed for explanation purpose):
DefaultValueAccessor is a good example of wrapping a DOM element. It writes value to the DOM element. It listens to
blur events of the home element and call the registered callbacks.
Any component or directive can implement
ControlValueAccessor interface and register itself as a