1

我使用FormBuilder创建了一个表单,并且我想将Validator添加到formGroup。 这里是我的代码:Angular2:如何为FormGroup创建自定义验证器?

this.myForm = fb.group({ 
     'name': ['', [Validators.maxLength(50), Validators.required]], 
     'surname': ['', [Validators.maxLength(50), Validators.required]], 
     'address': fb.group({ 
       'street': ['', Validators.maxLength(300)], 
       'place': [''], 
       'postalcode': [''] 
     }), 
     'phone': ['', [Validators.maxLength(25), phoneValidator]], 
     'email': ['', emailValidator] 
    }); 

我想有条件验证添加到一些地址的在一定条件下formControls的。

所以我以下列方式增加了一个validator

 'address': fb.group({ 
       'street': ['', Validators.maxLength(300)], 
       'place': [''], 
       'postalcode': [''] 
     }), { validator: fullAddressValidator }) 

然后,我开始创建一个验证器的地址FormGroup

export const fullAddressValidator = (control:FormGroup) => { 
    var street:FormControl = control.controls.street; 
    var place:FormControl = control.controls.place; 
    var postalcode:FormControl = control.controls.postalcode; 

    if (my conditions are ok) { 
     return null; 
    } else { 
     return { valid: false }; 
    } 
}; 

我需要添加以下条件:

  1. 如果所有字段都为空,则表单有效
  2. 如果其中一个字段被填充,那么所有的领域都必须按规定
  3. 如果place的国家(而不是市)postalcode 是可选的情况下
  4. 如果postalcode填充,则zipValidator必须
    添加到其formControl

因此,有可能Angular2 Validators添加到FormGroup一定的条件? 如果是这样,如何实现我的条件?我可以在另一个验证器的源代码中使用setValidators()updateValueAndValidity()吗?

回答

2

创建一个函数,参数,返回一个验证器函数

export const fullAddressValidator = (condition) => (control:FormGroup) => { 
    var street:FormControl = control.controls.street; 
    var place:FormControl = control.controls.place; 
    var postalcode:FormControl = control.controls.postalcode; 

    if (my conditions are ok) { 
     return null; 
    } else { 
     return { valid: false }; 
    } 
}; 

,并使用它像

'address': fb.group({ 
      'street': ['', Validators.maxLength(300)], 
      'place': [''], 
      'postalcode': [''] 
    }), { validator:() => fullAddressValidator(condition) }) 
+0

我应该作为参数传递什么? – smartmouse

+0

该病症。条件可以是值,组件的方法或类实例或函数。您可以在验证程序中使用它来执行额外的检查,这些检查可以访问验证程序之外的范围。如果您传递方法,则该方法可以在验证检查时访问组件状态。确保在传递方法或函数时使用'()=>'箭头函数语法。 –

+0

我目前在我的自定义验证器中有整个'FormGroup',所以所有的条件都可以在它的'FormControl'上进行检查。我错了吗? – smartmouse

0

是的,它可以设置一个FormGroup自定义验证内部FormControl验证。这里是我的需求的解决方案:

export const fullAddressValidator = (control:FormGroup):any => { 
    var street:FormControl = control.controls.street; 
    var place:FormControl = control.controls.place; 
    var postalcode:FormControl = control.controls.postalcode; 

    if (!street.value && !place.value && !postalcode.value) { 
     street.setValidators(null); 
     street.updateValueAndValidity({onlySelf: true}); 
     place.setValidators(null); 
     place.updateValueAndValidity({onlySelf: true}); 
     postalcode.setValidators(null); 
     postalcode.updateValueAndValidity({onlySelf: true}); 

     return null; 
    } else { 
     street.setValidators([Validators.required, Validators.maxLength(300)]); 
     street.updateValueAndValidity({onlySelf: true}); 
     place.setValidators([Validators.required]); 
     place.updateValueAndValidity({onlySelf: true}); 
     if (place.value instanceof Country) { 
      postalcode.setValidators(Validators.maxLength(5)); 
      postalcode.updateValueAndValidity({onlySelf: true}); 
     } else { 
      postalcode.setValidators([zipValidator()]); 
      postalcode.updateValueAndValidity({onlySelf: true}); 
     } 
    } 

    if (street.invalid || place.invalid || postalcode.invalid) { 
     return {valid: false}; 

    } else { 
     return null; 
    } 
};