【问题标题】:Angular2: how to create custom validator for FormGroup?Angular2:如何为 FormGroup 创建自定义验证器?
【发布时间】:2017-04-04 20:39:31
【问题描述】:

我正在使用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

那么,是否可以在特定条件下将 Angular2 Validators 添加到 FormGroup? 如果是,如何执行我的条件?我可以在另一个验证器的源代码中使用setValidators()updateValueAndValidity() 吗?

【问题讨论】:

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


    【解决方案1】:

    创建一个接受参数并返回验证器函数的函数

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

    【讨论】:

    • 我应该传递什么作为参数?
    • 条件。条件可以是值、组件的方法或类实例或函数。您可以在验证器内部使用它来执行可以访问验证器外部范围的附加检查。如果您传递一个方法,则该方法可以在验证检查时访问组件状态。确保在传递方法或函数时使用 ()=> 箭头函数语法。
    • 我目前在我的自定义验证器中拥有整个FormGroup,因此可以在其FormControls 上检查所有条件。我错了吗?
    • 我还没有找到从FormGroup 获取脏状态的方法。但是您可以使用我的方法从外部获取它。我认为从组或控件订阅statusChanges 可以提供该信息。我不希望这与 Angular 传递给验证器的 FormGroup 一起使用,因为它可能在调用验证器之前被标记为脏。
    • 为什么要dirty 状态?你知道如何在我的自定义验证器中将验证器添加到 formControl 吗?
    【解决方案2】:

    是的,可以在 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;
        }
    };
    

    【讨论】:

      猜你喜欢
      • 2017-03-03
      • 2013-02-04
      • 1970-01-01
      • 2017-10-03
      • 2018-12-08
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 2017-11-09
      相关资源
      最近更新 更多