Angular2相互依赖的表单字段验证

时间:2016-06-14 14:41:55

标签: forms validation angular

我有两个表单字段,如果填写第一个字段,则第二个字段是必填字段。如果我尝试使用自定义验证器在Angular2中执行此操作,则仅在初始化和特定字段更改时触发验证器。

案例: - 用户填写字段1 - 字段2应该是必需的,但直到用户实际更改字段2(触发自定义验证)。

private createForm():void {
 this.testForm = this._formBuilder.group({
  'field1': [],
  'field2': ['', this.validateRequired()]
 });
}

private validateRequired(){
 console.log("something", this);
 let component = this;

 return (control: Control): { [s: string]: boolean } => {
   return component.testModel.field1 && !control.value {"required":true} : null;
 }
}

请参阅此plunkr:http://plnkr.co/edit/PEY2QIegkqo8BW1UkQS5?p=preview

修改

现在我订阅了field1的valueChange observable,当更改时,对field2执行手动检查,如:

this.testForm.controls['field1'].valueChanges.subscribe(
  value => {
   component.testForm.controls['field2].updateValueAndValidity();        
  }
)

但我觉得必须有更好的方法来做到这一点。

2 个答案:

答案 0 :(得分:1)

你可以像这样使用全局验证器:

private createForm():void {
 this.testForm = this._formBuilder.group({
  'field1': [],
  'field2': ['', this.validateRequired()]
 }, {
  validator: this.someGlobalValidator // <-----
 });
}

someGlobalValidator(group: ControlGroup) { // <-----
  var valid = false;

  for (name in group.controls) {
    var val = group.controls[name].value

    (...)
  }

  if (valid) {
    return null;
  }

  return {
    someValidationError: true
  };
}

答案 1 :(得分:0)

为了解决Arne的评论,我想稍微扩展Thierry的答案。为了在formgroup级别验证器中处理多个字段和可能的多个验证的验证,解决方案是从验证器返回一个函数,然后返回一个指示错误类型的对象。下面是一个字段匹配验证器的示例,为了说明这一点,我添加了一些额外的错误。请注意,它返回一个可能具有多个属性的对象,其中每个对象属性都是任何字符串,值为布尔值。

export function FieldMatchingValidator(field1: string, field2 :string) {

    return (cg: FormGroup): { [s: string]: boolean } => {
        let retVal = null;
        let f1 = cg.controls[field1];
        let f2 = cg.controls[field2];
        retVal = f1.value === f2.value ? null : { fieldMismatch: true };
        if(somecondition){
            retVal['someerror'] = true;
        }
        if(someothercondition){
            retVal['someothererror'] = true;
        }
        return retVal;
    }
}

当此验证程序运行时,如果遇到错误条件,则表单的errors属性将填充返回的对象,其中一个或多个属性指示不同的错误。然后,您只需要在具有验证错误的控件上设置适当的角度属性设置。

<div *ngIf="myForm.hasError('fieldMismatch')">
Field Mismatch
</div>

<div *ngIf="myForm.hasError('someerror')">
Some Error
</div>

<div [class.Errors]="myForm.hasError('someothererror')">
Some Other Error
</div>
相关问题