遍历嵌套的表单组并将每个表单控件值更改为 null,如果它有模式错误
Loop through nested formgroup and change each form control value to null if it has pattern error
我必须查明我的表单控件是否有模式错误。如果它有模式错误,那么我必须将该 formcontrol 的值更改为 null。
我写了一个递归方法,它调用自身来检查表单控件是否有一个模式错误,然后它最终 return 是真还是假,但我想要的是改变它的值表单控件为 null
这是我的递归函数,
hasPatternError(form: AbstractControl, isRecursion = false): boolean {
if (!isRecursion) {
this.patternErrors = [];
}
if (form instanceof FormControl) {
return form.hasError('pattern') === true ?? null;
}
if (form instanceof FormArray) {
form?.controls?.forEach(e => {
this.hasAnyPatternError(e, true);
});
}
if (form instanceof FormGroup) {
Object.keys(form.controls).forEach(key => {
const error = this.hasAnyPatternError(form.get(key), true);
if (error === true) {
this.patternErrors.push(error);
}
});
return this.patternErrors.length > 0 ? true : false;
}
}
这是我的表单,正在监听值变化事件。在 change 事件中,我调用上面的递归方法来查找是否有任何表单控件有模式错误,但坚持将该表单控件的值更改为 null。
注意:我希望方法 (hasPatternError) return 一个对象(将错误转换为 null 并且不希望表单实时更改)
ngOnInit() {
this.myForm = this.fb.group({
name: [''],
address: this.fb.group({
street: [''],
zip: [''],
licenseNo: ['', [Validators.required, Validators.pattern(/^[a-z0-9]{10}$/i)]],
})
})
this.myForm.valueChanges.subscribe(
data => {
console.log(this.hasAnyPatternError(this.myForm))
}
);
}
这是我在 stackblitz
上的 code
当您推送错误时,您已经引用了 form
和控件 key
。
设置当时控件上的值。
- 因为你是用递归来做的,所以看起来有些奇怪
我在你的 stackblitz 中玩它时的行为。
- 但是我想说的是,控件上有一个
setValue
功能,只需要
以确定在您的逻辑中使用它的最佳方式。
- 甚至可能需要探索去抖动等行为,让用户有时间完成击键。
if (!form.controls[key]['controls'] && error === true) {
setTimeout(()=>{
form.controls[key].setValue('');
},3000)
this.patternErrors.push(error);
}
我添加了一个 setTimeout
等待 3 秒,然后再将值设置回 ''
以模拟去抖...它似乎有效,但这不是一个合适的解决方案,只是说明了原理您需要探索如何在递归中正确利用 setValue
。
STACKBLITZ
https://stackblitz.com/edit/ng-nested-formgroup-zet7ry?file=src/app/app.component.ts
不是 return 表示模式错误的布尔值,而是 return 有模式错误的控件。
findPatternErrors(formItem: AbstractControl): FormControl[] {
if (formItem instanceof FormControl) {
if (formItem.hasError('pattern')) {
return [formItem];
}
return [];
}
if (formItem instanceof FormArray) {
const patternErrors: FormControl[] = [];
formItem.controls?.forEach(arrayItem => {
const ctrls = this.findPatternErrors(arrayItem);
Array.prototype.push.apply(patternErrors, ctrls);
});
return patternErrors;
}
if (formItem instanceof FormGroup) {
const patternErrors: FormControl[] = [];
Object.keys(formItem.controls).forEach(key => {
const ctrls = this.findPatternErrors(formItem.get(key));
if (ctrls.length) {
Array.prototype.push.apply(patternErrors, ctrls);
}
});
return patternErrors;
}
}
https://stackblitz.com/edit/ng-nested-formgroup-fmhfcs?file=src/app/app.component.ts
我必须查明我的表单控件是否有模式错误。如果它有模式错误,那么我必须将该 formcontrol 的值更改为 null。
我写了一个递归方法,它调用自身来检查表单控件是否有一个模式错误,然后它最终 return 是真还是假,但我想要的是改变它的值表单控件为 null
这是我的递归函数,
hasPatternError(form: AbstractControl, isRecursion = false): boolean {
if (!isRecursion) {
this.patternErrors = [];
}
if (form instanceof FormControl) {
return form.hasError('pattern') === true ?? null;
}
if (form instanceof FormArray) {
form?.controls?.forEach(e => {
this.hasAnyPatternError(e, true);
});
}
if (form instanceof FormGroup) {
Object.keys(form.controls).forEach(key => {
const error = this.hasAnyPatternError(form.get(key), true);
if (error === true) {
this.patternErrors.push(error);
}
});
return this.patternErrors.length > 0 ? true : false;
}
}
这是我的表单,正在监听值变化事件。在 change 事件中,我调用上面的递归方法来查找是否有任何表单控件有模式错误,但坚持将该表单控件的值更改为 null。
注意:我希望方法 (hasPatternError) return 一个对象(将错误转换为 null 并且不希望表单实时更改)
ngOnInit() {
this.myForm = this.fb.group({
name: [''],
address: this.fb.group({
street: [''],
zip: [''],
licenseNo: ['', [Validators.required, Validators.pattern(/^[a-z0-9]{10}$/i)]],
})
})
this.myForm.valueChanges.subscribe(
data => {
console.log(this.hasAnyPatternError(this.myForm))
}
);
}
这是我在 stackblitz
上的 code当您推送错误时,您已经引用了 form
和控件 key
。
设置当时控件上的值。
- 因为你是用递归来做的,所以看起来有些奇怪 我在你的 stackblitz 中玩它时的行为。
- 但是我想说的是,控件上有一个
setValue
功能,只需要 以确定在您的逻辑中使用它的最佳方式。 - 甚至可能需要探索去抖动等行为,让用户有时间完成击键。
if (!form.controls[key]['controls'] && error === true) {
setTimeout(()=>{
form.controls[key].setValue('');
},3000)
this.patternErrors.push(error);
}
我添加了一个 setTimeout
等待 3 秒,然后再将值设置回 ''
以模拟去抖...它似乎有效,但这不是一个合适的解决方案,只是说明了原理您需要探索如何在递归中正确利用 setValue
。
STACKBLITZ
https://stackblitz.com/edit/ng-nested-formgroup-zet7ry?file=src/app/app.component.ts
不是 return 表示模式错误的布尔值,而是 return 有模式错误的控件。
findPatternErrors(formItem: AbstractControl): FormControl[] {
if (formItem instanceof FormControl) {
if (formItem.hasError('pattern')) {
return [formItem];
}
return [];
}
if (formItem instanceof FormArray) {
const patternErrors: FormControl[] = [];
formItem.controls?.forEach(arrayItem => {
const ctrls = this.findPatternErrors(arrayItem);
Array.prototype.push.apply(patternErrors, ctrls);
});
return patternErrors;
}
if (formItem instanceof FormGroup) {
const patternErrors: FormControl[] = [];
Object.keys(formItem.controls).forEach(key => {
const ctrls = this.findPatternErrors(formItem.get(key));
if (ctrls.length) {
Array.prototype.push.apply(patternErrors, ctrls);
}
});
return patternErrors;
}
}
https://stackblitz.com/edit/ng-nested-formgroup-fmhfcs?file=src/app/app.component.ts