如何在模板驱动的表单中为 ngModelGroup 添加自定义验证
How to add custom validation for ngModelGroup in Template driven forms
我正在使用模板驱动表单方法。我想在 ngModelGroup
上添加自定义验证。即,如果填写了一个字段,则还必须填写所有字段。
<form #f="ngForm">
<div ngModelGroup="address">
<input type="email" name="house_number" class="form-control" ngModel>
<input type="email" name="street_number" class="form-control" ngModel>
</div>
</form>
我在网上搜索,只找到像 this 这样的文章,这些文章仅在输入级别而不是 ngModelGroup
级别讨论自定义验证。其他文章讨论了我无法实现的 Reactive 表单。
任何帮助将不胜感激。
由于您处理模板驱动的表单,因此最好创建将验证器添加到您的地址组的指令:
@Directive({
selector: '[ngModelGroup][requiredIfOneFilledValidator]',
providers: [{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AddressValidator),
multi: true
}]
})
export class RequiredIfOneFilledValidator implements Validator {
validate(group: AbstractControl): ValidationErrors | null {
const controls = (group as FormGroup).controls; // we expect FormGroup here
const controlNames = Object.keys(controls);
const filledCount = controlNames.filter(name => !!controls[name].value).length;
return filledCount > 0 && filledCount < controlNames.length ? { required: true } : null;
}
}
现在您可以在模板中轻松使用此验证器:
<div ngModelGroup="address" requiredIfOneFilledValidator>
如果您想检查组是否有效,只需使用模板引用变量:
<div ngModelGroup="address" requiredIfOneFilledValidator #addressGroup="ngModelGroup">
...
</div>
<p>Group valid? {{addressGroup.valid}}</p>
或者只检查整个表单的状态:
Form valid? {{ f.valid }}
如果创建新指令是一个问题,您可以在现有组件中进行更改。您可以添加 div 以在 html 文件中向用户显示错误消息。
<form (ngSubmit)="validateData(f)" #f="ngForm">
<div ngModelGroup="address">
<input type="email" name="house_number" class="form-control" required ngModel>
<div style="color:red;display:none;" id="errorMsg">
This field cannot be empty
</div>
<input type="email" name="street_number" class="form-control" ngModel>
</div>
<button type="submit">Submit</button>
</form>
在组件部分,您可以根据需要访问表单值和 show/hide 验证。
address:any;
validateData(f) {
console.log("Form Values : "+ f.value);
this.address = f.value.address;
if(!this.address.house_number){
//code to show/hide the message
var x = document.getElementById("errorMsg");
x.style.display="block";
}
//to check form validity
if (f.valid) {
//do something
}
}
}
我正在使用模板驱动表单方法。我想在 ngModelGroup
上添加自定义验证。即,如果填写了一个字段,则还必须填写所有字段。
<form #f="ngForm">
<div ngModelGroup="address">
<input type="email" name="house_number" class="form-control" ngModel>
<input type="email" name="street_number" class="form-control" ngModel>
</div>
</form>
我在网上搜索,只找到像 this 这样的文章,这些文章仅在输入级别而不是 ngModelGroup
级别讨论自定义验证。其他文章讨论了我无法实现的 Reactive 表单。
任何帮助将不胜感激。
由于您处理模板驱动的表单,因此最好创建将验证器添加到您的地址组的指令:
@Directive({
selector: '[ngModelGroup][requiredIfOneFilledValidator]',
providers: [{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AddressValidator),
multi: true
}]
})
export class RequiredIfOneFilledValidator implements Validator {
validate(group: AbstractControl): ValidationErrors | null {
const controls = (group as FormGroup).controls; // we expect FormGroup here
const controlNames = Object.keys(controls);
const filledCount = controlNames.filter(name => !!controls[name].value).length;
return filledCount > 0 && filledCount < controlNames.length ? { required: true } : null;
}
}
现在您可以在模板中轻松使用此验证器:
<div ngModelGroup="address" requiredIfOneFilledValidator>
如果您想检查组是否有效,只需使用模板引用变量:
<div ngModelGroup="address" requiredIfOneFilledValidator #addressGroup="ngModelGroup">
...
</div>
<p>Group valid? {{addressGroup.valid}}</p>
或者只检查整个表单的状态:
Form valid? {{ f.valid }}
如果创建新指令是一个问题,您可以在现有组件中进行更改。您可以添加 div 以在 html 文件中向用户显示错误消息。
<form (ngSubmit)="validateData(f)" #f="ngForm">
<div ngModelGroup="address">
<input type="email" name="house_number" class="form-control" required ngModel>
<div style="color:red;display:none;" id="errorMsg">
This field cannot be empty
</div>
<input type="email" name="street_number" class="form-control" ngModel>
</div>
<button type="submit">Submit</button>
</form>
在组件部分,您可以根据需要访问表单值和 show/hide 验证。
address:any;
validateData(f) {
console.log("Form Values : "+ f.value);
this.address = f.value.address;
if(!this.address.house_number){
//code to show/hide the message
var x = document.getElementById("errorMsg");
x.style.display="block";
}
//to check form validity
if (f.valid) {
//do something
}
}
}