Комментарии 10
У меня возник вопрос. Допустим, наш компонент реализован с использованием реактивной формы внутри и поддерживает валидаторы. Существует ли стандартный подход для поддержки метода markAsTouched в таком компоненте?
Объясню проблему… На кастомный контрол, в родительской форме, установлен валидатор, проверяющий пустое значение. Далее вызывается метод markAsTouched. Контрол в родительской форме становится invalid, так как значение пустое. Однако статус внутренней формы кастомного контрола не меняется, соотвественно не выполняется поведение при статусе invalid. Есть ли способ задавать коллбек для метод markAsTouched по аналогии с onChange?
Существует ли стандартный подход для поддержки метода markAsTouched в таком компоненте?
Touched событий у формы в принципе нету… Но как всегда есть костыль — можно проверять touched
внутри DoCheck
и обновлять внутреннюю форму. Правда в этом случае есть проблемы с тем как получить ссылку на внешний FormControl
, легче и лучше всего это сделать через @Input() formControl
(правда оно не будет работать с formControlName
, но зато максимально прозрачно и без костылей...)
Так и делал, но что-то мне подсказывает, что я решаю задачу неправильно. Либо не стоит использовать реактивную форму внутри, либо есть возможность иначе связать родительскую форму с внутренней.
Всё нормально, расслабьтесь, это ангуляр, тут подобных костылей на каждом шагу по десятку...
Ну а если серьезно, то
либо есть возможность иначе связать родительскую форму с внутренней.
Никак.
Либо не стоит использовать реактивную форму внутри
Это зависит от того что вам надо, возможно, в вашем случае можно заменить родительный контрол на FormGroup
(которая сейчас внутри), это решит проблемы с touched
, но в сложных формах, когда это невозможно — только костылить пытаясь заставить это всё работать....
Если я правильно вас понял, то есть необходимость в обработке ошибок внутри кастомного контрола
Для этого вам нужна ссылка на FormControl из внешней формы
Сделать это достаточно просто с DI (и долей
в классе кастом контрола инжектим:
constructor(
@Optional() @Self() public control: NgControl
) {
if (control) {
control.valueAccessor = this; // иначе ошибка Uncaught Error: Template parse errors: Cannot instantiate cyclic dependency! NgControl
}
}
и в метаданных убираем провайдер NG_VALUE_ACCESSOR. Взято отсюда.
registerOnTouched(fn: any) — аналогично registerOnChange, определяет обработчик на touch-событияЧто вы имеете в виду по touch-событиями?
registerOnTouched на самом деле определяет обработчик onBlur: angular.io/api/forms/ControlValueAccessor#registerOnTouched
Свои Custom Controls в Angular