我在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,但一切看起来都不错。
我试图通过检查控件集合中的status属性来查找。但我想知道是否有办法找到无效的并显示给用户?
答案 0 :(得分:69)
您可以简单地遍历每个控件并检查状态:
public findInvalidControls() {
const invalid = [];
const controls = this.AddCustomerForm.controls;
for (const name in controls) {
if (controls[name].invalid) {
invalid.push(name);
}
}
return invalid;
}
答案 1 :(得分:4)
我刚刚解决了这个问题:每个表单字段都有效,但是表单本身仍然无效。
原来,我在FormArray上设置了“ Validator.required”,在其中动态添加/删除控件。因此,即使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;
}
答案 2 :(得分:3)
在Chrome的DevTools下,选择“控制台”标签。
在控制台提示符下,键入命令:
document.getElementsByClassName('ng-invalid')
在这种情况下,带下划线的文本用于格式控件listen-address
。带有圆圈的文本.ng-invalid
表示该控件无效。
注意:已在Chrome中测试
答案 3 :(得分:3)
现在,在角度9中,您可以使用markAllAsTouched()方法显示无效的控件验证器:
this.AddCustomerForm.markAllAsTouched();
答案 4 :(得分:1)
表单和所有控件都扩展了angular类AbstractControl。每个实现都有一个验证错误的访问者。
let errors = this.AddCustomerForm.errors
// errors is an instance of ValidatorErrors
api文档包含所有引用 https://angular.io/api/forms/AbstractControl
修改强>
我认为错误访问器以这种方式工作但是这个链接到github表明还有一些其他人和我一样的想法 https://github.com/angular/angular/issues/11530
在任何情况下,通过使用控件访问器,您可以迭代表单中的所有formControl。
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's subcontrols too
})
答案 5 :(得分:1)
如果表单中没有太多字段,则只需按F12键并将鼠标悬停在控件上,就可以看到带有该字段原始值/触摸值/有效值的弹出式窗口- “#fieldname.form-control.ng-untouched.ng-invalid”。
答案 6 :(得分:1)
尝试
findInvalidControls(f: FormGroup) {
const invalid = [];
const controls = f.controls;
for (const name in controls) {
if (controls[name].invalid) {
invalid.push(name);
}
}
return invalid;
}
答案 7 :(得分:1)
这将记录所有控件的名称?
for (let el in this.ReactiveForm.controls) {
if (this.ReactiveForm.controls[el].errors) {
console.log(el)
}
}
您可以从中创建一个数组或字符串并显示给用户
答案 8 :(得分:1)
就我而言,我禁用了所有表单控件。
这似乎是 Angular 中的一个开放错误:https://github.com/angular/angular/issues/39287
答案 9 :(得分:0)
我自由地改进了 AngularInDepth.com -s代码,以便它也以嵌套形式递归搜索无效输入。它是否由FormArray或FormGroup嵌套。只需输入顶级formGroup,它将返回所有无效的FormControl。
如果您要将FormControl检查和对无效数组功能的添加分开到一个单独的函数中,则可以略去一些“ instanceof”类型的检查。这样会使函数看起来更简洁,但是我需要一个全局的单个函数选项来获取所有无效formControl的平面数组,这就是解决方案!
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;
}
答案 10 :(得分:0)
您可以记录格式为console.log(this.addCustomerForm.value)
的值,它将控制台所有控件的值,然后null或“”(空)字段表示无效的控件
答案 11 :(得分:0)
解决上述问题的更简洁且不可变的递归版本:
P.S:这两种方法你都需要。
<块引用>工作测试直到 Angular 11
<块引用>如果编译器抱怨flatMap,参考这个(Typescript flatMap, flat, flatten doesn't exist on type any[]),不要伪造重启ng serve
findInvalidControls(controls = this.defaultFormGroup.controls) {
const ctrls = Object.values(controls);
const names = Object.keys(controls);
return ctrls.map((a,i) => [a, i])
.filter(a => (a[0] as FormControl).invalid)
.flatMap(a => {
if (a[0] instanceof FormArray) {
return this.findInvalidArrayControls(a[0].controls);
} else if (a[0] instanceof FormGroup) {
return this.findInvalidControls(a[0].controls);
} else {
return names[a[1] as number];
}
});
}
findInvalidArrayControls(controls: AbstractControl[]) {
const ctrls = Object.values(controls);
const names = Object.keys(controls);
return ctrls.map((a,i) => [a, i])
.filter(a => (a[0] as FormControl).invalid)
.flatMap(a => {
if (a[0] instanceof FormArray) {
return this.findInvalidArrayControls(a[0].controls);
} else if (a[0] instanceof FormGroup) {
return this.findInvalidControls(a[0].controls);
}
else {
return names[a[1] as number];
}
});
}
答案 12 :(得分:0)
所以我也反击了这条龙。 就像勇敢的骑士一样,我首先收集了my weapons,阅读了the maps,然后与这头可怕的野兽战斗。
对于复杂的形式或结构,这不是一个可接受的答案,但我发现它适用于简单的形式或结构,没有太多复杂性
代码执行以下操作:
isFormValid = () :boolean =>
Object.values(this.form.controls)
.filter(c => c.invalid).length === 0
// or single lined
isFormValid = () :boolean => Object.values(this.form.controls).filter(c => c.invalid).length === 0
您可以在您想要的地方、提交按钮、提交时或您自己的最佳位置使用它。
答案 13 :(得分:-1)
在html页面中检查表单控件值为空或为空
表单控制值:{{formname.value | json}}