Angular 13中的自定义验证器(强制选中至少一个复选框)不起作用



我正在使用Angular 13,我正在尝试为表单的一些字段应用自定义验证器。比如我有:

输入1
  • 输入2
  • 复选框1
  • 复选框2
  • 复选框
  • 3

,我在每个字段中绑定了一个ngForm和一个双向的ngModel:

<form class="flex-col text-center" #inspectionForm="ngForm">
...
...
...
<div class="input-group input-group-sm mb-3">
<input class="form-control" type="text " [(ngModel)]="inspectionService.checkbox1" name="checkbox1" required />
</div>
</form>
<button [disabled]="!inspectionForm.form.valid" type="button" class="btn bg-primary-tb text-white mt-3 col-4" (click)="submit();">Continue</button>

我想只对复选框应用验证器。它必须强制用户检查至少一个。

关键是使用[disabled]="!inspectionForm.form.valid"

禁用按钮这就是我在form.component.ts中的代码:

@ViewChild('inspectionForm') inspectionForm ?: NgForm;
atLeastOneValidator(checkboxes: string[]): ValidatorFn{
return (control: AbstractControl): { [key: string]: boolean } | null => {
for(let i = 0; i < checkboxes.length; i++){
if(this.inspectionForm!.form.get(checkboxes[i])?.value === true) return null;
}
return  { 'atLeastOne': true };
}
}

ngOnInit(): void {
let checkboxes = ['checkbox1', 'checkbox2', 'checkbox3']; // Checkboxes' names
checkboxes.forEach(item => {
this.inspectionForm?.form.controls[item].setValidators([this.atLeastOneValidator(checkboxes)]);
this.inspectionForm?.form.controls[item].updateValueAndValidity({onlySelf: true});
})

但它不起作用。我不知道我做错了什么,或者我跳过了什么

应该对表单进行多控件验证,而不是对控件进行验证。


form = this.formBuilder.group({ /* ... */ }, [atLeastOne(['cb1'])]);
// Some file somewhere
export function atLeastOne(boxNames) {
return function(form) {
const boxes = Object.entries(form.controls)
.filter(([key]) => boxNames.includes(key))
.map(([, v]) => v);
const valid = boxes.some(box => !!box.value);
return valid ? null : { 'atleastone': true };
}
}

问题是"this"对你的功能没有任何价值atLeastOneValidator

你可以使用bind(this)(它的javascript绑定)

this.inspectionForm?.form.controls[item].setValidators(
[this.atLeastOneValidator(checkboxes).bind(this)]);

但是要确保表单在函数atLeastOneValidator

中或"reach"使用control.parent

的表单
atLeastOneValidator(checkboxes: string[]): ValidatorFn {
return (control: AbstractControl): { [key: string]: boolean } | null => {
const parent = control.parent as FormGroup;
if (!parent)
return null;
const success = checkboxes.reduce((a,b)=>a || parent.get(b).value,false);
return success ? null : { atLeastOne: true };
};
}

但是要小心,只有当有一个输入关系和输入改变时,或者当我们手动调用updateValueAndValidity时,才会检查FormControl是否有效。

因此,我们可以创建一个函数
updateValueAndValidity(...checkboxes:string[])
{
checkboxes.forEach((x) => {
this.form.get(x).updateValueAndValidity({emitEvent:false})
});
}
并调用。html
<form [formGroup]="form">
<input type="checkbox" formControlName="checkbox1" 
(change)="updateValueAndValidity('checkbox2','checkbox3')"/>
<input type="checkbox" formControlName="checkbox2" 
(change)="updateValueAndValidity('checkbox1','checkbox3')"/>
<input type="checkbox" formControlName="checkbox3" 
(change)="updateValueAndValidity('checkbox1','checkbox2')"/>
</form>

或者订阅valuesChanges

相关内容

最新更新