Angular - 将自定义验证器分配给 FormGroup
Posted
技术标签:
【中文标题】Angular - 将自定义验证器分配给 FormGroup【英文标题】:Angular - assign custom validator to a FormGroup 【发布时间】:2018-12-08 04:49:12 【问题描述】:我需要将自定义验证器分配给 FormGroup。我可以在创建 FormGroup 时这样做:
let myForm : FormGroup;
myForm = this.formBuilder.group(
myControl1: defaultValue,
myControl2: defaultValue
, validator: this.comparisonValidator )
comparisonValidator(g: FormGroup)
if (g.get('myControl1').value > g.get('myControl2'.value))
g.controls['myControl1'].setErrors( 'value2GreaterThanValue1': true );
return;
我有一种情况,我需要在实例化 FormGroup 之后添加自定义验证器,所以我尝试在实例化 myForm
之后执行此操作,而不是添加验证器当窗体实例化时:
let myForm : FormGroup;
myForm = this.formBuilder.group(
myControl1: defaultValue,
myControl2: defaultValue
)
this.myForm.validator = this.comparisonValidator;
这给了我一个编译器错误:
Type '(g: FormGroup) => void' is not assignable to type 'ValidatorFn'.
Type 'void' is not assignable to type 'ValidationErrors'.
如何为我的FormGroup
分配一个验证器,以便将formGroup
作为参数传递给我的comparisonValidator
函数?
更新 - 我在comparisonValidator
中添加了一行显示我正在执行setErrors
的位置,以便更清楚地了解我是如何尝试设置验证错误的。
【问题讨论】:
可以使用setValidators()添加动态验证器。但特定于特定控件,您可以一次更新 您收到此错误是因为您从comparisonValidator
函数返回 void
。更改函数以在最后一行(不在 if 语句内)返回 null
,错误应该消失了。
【参考方案1】:
我创建了一个stackblitz 看看。
在component.ts文件中
import Component from '@angular/core';
import FormBuilder,FormGroup, ValidationErrors, ValidatorFn from '@angular/forms'
@Component(
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
)
export class AppComponent
myForm: FormGroup;
defaultValue = 20;
constructor(private formBuilder: FormBuilder)
this.myForm = this.formBuilder.group(
myControl1: this.defaultValue,
myControl2: this.defaultValue
);
debugger
this.myForm.setValidators(this.comparisonValidator())
public comparisonValidator() : ValidatorFn
return (group: FormGroup): ValidationErrors =>
const control1 = group.controls['myControl1'];
const control2 = group.controls['myControl2'];
if (control1.value !== control2.value)
control2.setErrors(notEquivalent: true);
else
control2.setErrors(null);
return;
;
在component.html文件中
<div>
<form [formGroup]="myForm">
<input formControlName="myControl1" type="number">
<input formControlName="myControl2" type="number">
<br>Errors: myForm.get('myControl2').errors | json
</form>
</div>
【讨论】:
谢谢阿努拉达。为了澄清我在问什么,我试图只添加验证器 afterFormGroup
被实例化,而不是添加它 when 表单被实例化。我对问题进行了一些编辑以使其更清楚。
@ChrisHalcrow 我已经更新了答案。 nd 您可以在here 中找到一个工作示例。【参考方案2】:
要在实例化 formGroup 后设置任何验证器(预定义或自定义),您需要使用 FormGroup 的 setValiators() 方法。 例如:
let myFormGroup = this. _fb.group(
control1: new FormControl('1', [])
);
myFormGroup.setValidators(this.customValidators());
customValidators(): ValidatorFn
let myFun = (cc: FormGroup): ValidationErrors =>
if(cc.valid) return null;
else return something: 'someError';
;
return myFun;
You can play here.
【讨论】:
比从验证器返回任何更好的解决方案。【参考方案3】:感谢@Anuradha Gunasekara - 他的回答是最正确和最完整的解决方案。我的错误的“快速修复”只是在验证器上添加any
的返回类型。我仍然可以将自定义验证器分配给FormGroup
,并且FormGroup
将作为参数隐式传递给我的自定义验证器。此代码将起作用:
let myForm : FormGroup;
myForm = this.formBuilder.group(
myControl1: defaultValue,
myControl2: defaultValue
)
this.myForm.validator = this.comparisonValidator;
comparisonValidator(g: FormGroup) : any
if (g.get('myControl1').value > g.get('myControl2'.value))
g.controls['myControl1'].setErrors( 'value2GreaterThanValue1': true );
【讨论】:
【参考方案4】:删除所有表单控件空白表单表单组
自定义验证器:
export function formGroupRemoveWhitespaceValidator(form: FormGroup): ValidationErrors | null
const keys: string[] = Object.keys(form.controls);
if (keys.length)
keys.forEach(k =>
let control = form.controls[k];
if (control && control.value && !control.value.replace(/\s/g, '').length)
control.setValue('');
);
return null;
组件:
let myForm : FormGroup;
myForm = this.formBuilder.group(
myControl1: defaultValue,
myControl2: defaultValue
, validators: formGroupRemoveWhitespaceValidator );
【讨论】:
以上是关于Angular - 将自定义验证器分配给 FormGroup的主要内容,如果未能解决你的问题,请参考以下文章
Swift:将自定义类分配给所有 UINavigationController 是不是正确?
将自定义导航栏分配给 UINavigationController [重复]