Angular: формы
Template-driven vs Reactive Forms
- Template-driven — логика формы в шаблоне (директивы
ngModel), подходит для простых форм. - Reactive (model-driven) — форма описывается в коде (
FormControl,FormGroup), лучше масштабируется и тестируется.
Состояния контрола (CSS-классы)
| Состояние | Классы |
|---|---|
| Взаимодействие | ng-touched / ng-untouched |
| Валидность | ng-valid / ng-invalid |
| Изменение данных | ng-dirty / ng-pristine |
- touched — контрол потерял фокус (произошёл
blur) хотя бы раз, независимо от того, менялось ли значение. - pristine — данные ещё не менялись; dirty — пользователь изменил данные.
AbstractControl
Абстрактный класс — основа для form controls и form groups в reactive forms. Предоставляет общие свойства и методы:
- Валидация:
valid,invalid,errors,setErrors(). - Значение:
value,patchValue(),reset(). - Асинхронность:
setAsyncValidators(),updateValueAndValidity(). - События:
valueChanges,statusChanges. - Композиция:
addControl(),removeControl(),get(). - UI-флаги:
touched,dirty.
ControlValueAccessor & NG_VALUE_ACCESSOR
Реализация ControlValueAccessor + предоставление токена NG_VALUE_ACCESSOR позволяет создавать кастомные form-контролы, интегрированные с Forms API (two-way binding, валидация).
@Component({
selector: "app-custom-control",
template: "...",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomControlComponent),
multi: true,
},
],
})
export class CustomControlComponent implements ControlValueAccessor {
value: any;
writeValue(value: any): void { this.value = value; }
registerOnChange(fn: any): void { this.onChange = fn; }
registerOnTouched(fn: any): void { this.onTouched = fn; }
setDisabledState(isDisabled: boolean): void {}
private onChange = () => {};
private onTouched = () => {};
}