Как найти недействительные элементы управления в angular 4 реактивной форме
У меня есть реактивная форма в Angular, как показано ниже:
this.AddCustomerForm = this.formBuilder.group({
Firstname: ['', Validators.required],
Lastname: ['', Validators.required],
Email: ['', Validators.required, Validators.pattern(this.EMAIL_REGEX)],
Picture: [''],
Username: ['', Validators.required],
Password: ['', Validators.required],
Address: ['', Validators.required],
Postcode: ['', Validators.required],
City: ['', Validators.required],
Country: ['', Validators.required]
});
createCustomer(currentCustomer: Customer)
{
if (!this.AddCustomerForm.valid)
{
//some app logic
}
}
this.AddCustomerForm.valid возвращает false, но все выглядит хорошо.
Я попытался найти с проверкой свойства статуса в коллекции элементов управления. Но мне интересно, есть ли способ найти недействительные и показать пользователю?
Ответы
Ответ 1
Вы можете просто перебрать все элементы управления и проверить статус:
public findInvalidControls() {
const invalid = [];
const controls = this.AddCustomerForm.controls;
for (const name in controls) {
if (controls[name].invalid) {
invalid.push(name);
}
}
return invalid;
}
Ответ 2
Я только что боролся с этой проблемой: каждое поле формы является действительным, но все же сама форма является недействительной.
Оказывается, я установил Validator.required в FormArray, где элементы управления добавляются/удаляются динамически. Таким образом, даже если FormArray был пустым, он все еще требовался, и поэтому форма всегда была недействительной, даже если каждый видимый элемент управления был правильно заполнен.
Я не нашел недопустимую часть формы, потому что моя функция 'findInvalidControls' проверяла только FormControl, а не FormGroup/FormArray. Поэтому я немного его обновил:
/*
Returns an array of invalid control/group names, or a zero-length array if
no invalid controls/groups where found
*/
public findInvalidControlsRecursive(formToInvestigate:FormGroup|FormArray):string[] {
var invalidControls:string[] = [];
let recursiveFunc = (form:FormGroup|FormArray) => {
Object.keys(form.controls).forEach(field => {
const control = form.get(field);
if (control.invalid) invalidControls.push(field);
if (control instanceof FormGroup) {
recursiveFunc(control);
} else if (control instanceof FormArray) {
recursiveFunc(control);
}
});
}
recursiveFunc(formToInvestigate);
return invalidControls;
}
Ответ 3
Обе формы и все ваши элементы управления расширяют класс angular AbstractControl. Каждая реализация имеет аксессуар ошибок проверки.
let errors = this.AddCustomerForm.errors
// errors is an instance of ValidatorErrors
Api docs содержит все ссылки
https://angular.io/api/forms/AbstractControl
Edit
Я думал, что обработчик ошибок работал таким образом, но эта ссылка на github показывает, что есть другие люди, которые думали так же, как я
https://github.com/angular/angular/issues/11530
В любом случае, используя аксессуар для управления, вы можете перебирать все formControls в своей форме.
Object.keys(this.AddCustomerForm.controls)
.forEach( control => {
//check each control here
// if the child is a formGroup or a formArray
// you may cast it and check it subcontrols too
})
Ответ 4
Если у вас не много полей в форме, вы можете просто F12 и навести курсор на элемент управления, вы сможете увидеть всплывающее окно с полем нетронутым /touch/valid values- "# fieldname.form-control.ng -untouched.ng-инвалид".
Ответ 5
Я позволил себе усовершенствовать код AngularInDepth.com -s, чтобы он также рекурсивно искал недопустимые входные данные во вложенных формах. Вложен ли он в FormArray -s или FormGroup -s. Просто введите formGroup верхнего уровня, и он вернет все недействительные элементы FormControl.
Вы можете пропустить некоторые проверки типа instanceof, если бы вы разделили проверку FormControl и добавление к недействительным функциям массива в отдельную функцию. Это заставило бы функцию выглядеть намного чище, но мне нужна была глобальная, одиночная функция, опция, чтобы получить плоский массив всех недействительных formControls, и это решение!
findInvalidControls( _input: AbstractControl, _invalidControls: AbstractControl[] ): AbstractControl[] {
if ( ! _invalidControls ) _invalidControls = [];
if ( _input instanceof FormControl ) {
if ( _input.invalid ) _invalidControls.push( _input );
return _invalidControls;
}
if ( ! (_input instanceof FormArray) && ! (_input instanceof FormGroup) ) return _invalidControls;
const controls = _input.controls;
for (const name in controls) {
let control = controls[name];
switch( control.constructor.name )
{
case 'AbstractControl':
case 'FormControl':
if (control.invalid) _invalidControls.push( control );
break;
case 'FormArray':
(<FormArray> control ).controls.forEach( _control => _invalidControls = findInvalidControls( _control, _invalidControls ) );
break;
case 'FormGroup':
_invalidControls = findInvalidControls( control, _invalidControls );
break;
}
}
return _invalidControls;
}
Просто для тех, кому это нужно, чтобы им не приходилось кодировать это самим..
Редактировать # 1
Было запрошено, что он также возвращает недопустимые FormArray -s и FormGroups, поэтому, если вам это также нужно, используйте этот код
findInvalidControls( _input: AbstractControl, _invalidControls: AbstractControl[] ): AbstractControl[] {
if ( ! _invalidControls ) _invalidControls = [];
if ( _input instanceof FormControl ) {
if ( _input.invalid ) _invalidControls.push( _input );
return _invalidControls;
}
if ( ! (_input instanceof FormArray) && ! (_input instanceof FormGroup) ) return _invalidControls;
const controls = _input.controls;
for (const name in controls) {
let control = controls[name];
if (control.invalid) _invalidControls.push( control );
switch( control.constructor.name )
{
case 'FormArray':
(<FormArray> control ).controls.forEach( _control => _invalidControls = findInvalidControls( _control, _invalidControls ) );
break;
case 'FormGroup':
_invalidControls = findInvalidControls( control, _invalidControls );
break;
}
}
return _invalidControls;
}
Ответ 6
Вы можете console.log(this.addCustomerForm.value)
значение формы console.log(this.addCustomerForm.value)
, оно будет поддерживать все значения элемента управления, а затем пустые или пустые поля указывают на недопустимые элементы управления.