Angular2:如何为FormGroup创建自定义验证器?

时间:2016-11-21 12:37:44

标签: validation angular angular2-forms custom-validators angular2-formbuilder

我正在创建一个包含FormBuilder的表单,我想向Validator添加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
  5. 那么,在某些条件下可以将Angular2 Validators添加到FormGroup吗? 如果是的话,如何实现我的条件?我可以在另一个验证器的源代码中使用setValidators()updateValueAndValidity()吗?

2 个答案:

答案 0 :(得分: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) })

答案 1 :(得分:0)

是的,可以在FormControl自定义验证程序中设置FormGroup验证程序。这是我需要的解决方案:

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;
    }
};