为了账号安全,请及时绑定邮箱和手机立即绑定

Angular2验证器,它依赖于多个表单字段

/ 猿问

Angular2验证器,它依赖于多个表单字段

largeQ 2019-11-06 11:10:47

是否可以创建一个可以使用多个值来确定我的字段是否有效的验证器?


例如,如果客户首选的联系方式是通过电子邮件,则必须填写电子邮件字段。


谢谢。


更新了示例代码...


    import {Component, View} from 'angular2/angular2';

    import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';


    @Component({

        selector: 'customer-basic',

        viewInjector: [FormBuilder]

    })

    @View({

        templateUrl: 'app/components/customerBasic/customerBasic.html',

        directives: [formDirectives]

    })

    export class CustomerBasic {

        customerForm: ControlGroup;


        constructor(builder: FormBuilder) {

            this.customerForm = builder.group({

                firstname: [''],

                lastname: [''],

                validateZip: ['yes'],

                zipcode: ['', this.zipCodeValidator] 

                // I only want to validate using the function below if the validateZip control is set to 'yes'

            });

        }


        zipCodeValidator(control) {

            if (!control.value.match(/\d\d\d\d\d(-\d\d\d\d)?/)) {

                return { invalidZipCode: true };

            }

        }


    }


查看完整描述

3 回答

?
一只甜甜圈

为了重申其他已发布的方法,这是我一直在创建FormGroup不涉及多个组的验证器的方式。


对于此示例,只需提供password和confirmPassword字段的键名。


// Example use of FormBuilder, FormGroups, and FormControls

this.registrationForm = fb.group({

  dob: ['', Validators.required],

  email: ['', Validators.compose([Validators.required,  emailValidator])],

  password: ['', Validators.required],

  confirmPassword: ['', Validators.required],

  firstName: ['', Validators.required],

  lastName: ['', Validators.required]

}, {validator: matchingPasswords('password', 'confirmPassword')})

为了Validators获取参数,他们需要function使用FormGroup或FormControl作为参数返回a 。在这种情况下,我正在验证FormGroup。


function matchingPasswords(passwordKey: string, confirmPasswordKey: string) {

  return (group: FormGroup): {[key: string]: any} => {

    let password = group.controls[passwordKey];

    let confirmPassword = group.controls[confirmPasswordKey];


    if (password.value !== confirmPassword.value) {

      return {

        mismatchedPasswords: true

      };

    }

  }

}

从技术上讲,如果我知道它们的键,我可以验证任意两个值,但是我更愿意将其命名Validators为与它们将返回的错误相同的名称。可以修改该函数以采用第三个参数,该参数表示返回的错误的键名。


查看完整回答
反对 回复 2019-11-06
?
至尊宝的传说

戴夫的回答非常非常有帮助。但是,稍加修改可能会对某些人有所帮助。


如果需要在Control字段中添加错误,则可以保留表单和验证器的实际构造:


// Example use of FormBuilder, ControlGroups, and Controls

this.registrationForm= fb.group({

  dob: ['', Validators.required],

  email: ['', Validators.compose([Validators.required,  emailValidator])],

  password: ['', Validators.required],

  confirmPassword: ['', Validators.required],

  firstName: ['', Validators.required],

  lastName: ['', Validators.required]

}, {validator: matchingPasswords('password', 'confirmPassword')})

不必在上设置错误,而是ControlGroup在实际字段上进行设置,如下所示:


function matchingPasswords(passwordKey: string, passwordConfirmationKey: string) {

  return (group: ControlGroup) => {

    let passwordInput = group.controls[passwordKey];

    let passwordConfirmationInput = group.controls[passwordConfirmationKey];

    if (passwordInput.value !== passwordConfirmationInput.value) {

      return passwordConfirmationInput.setErrors({notEquivalent: true})

    }

  }

}


查看完整回答
反对 回复 2019-11-06
?
jeck猫

在为多个表单字段实现验证器时,必须确保在更新每个表单控件时重新评估验证器。大多数示例都没有提供针对这种情况的解决方案,但这对于数据一致性和正确行为非常重要。


请参阅我为Angular 2实现的自定义验证器的实现,其中考虑了这一点:https : //gist.github.com/slavafomin/17ded0e723a7d3216fb3d8bf845c2f30。


我otherControl.valueChanges.subscribe()用来监听其他控件的更改,并在其他控件更改时thisControl.updateValueAndValidity()触发另一轮验证。


我正在复制下面的代码以供将来参考:


匹配其他验证器

import {FormControl} from '@angular/forms';



export function matchOtherValidator (otherControlName: string) {


  let thisControl: FormControl;

  let otherControl: FormControl;


  return function matchOtherValidate (control: FormControl) {


    if (!control.parent) {

      return null;

    }


    // Initializing the validator.

    if (!thisControl) {

      thisControl = control;

      otherControl = control.parent.get(otherControlName) as FormControl;

      if (!otherControl) {

        throw new Error('matchOtherValidator(): other control is not found in parent group');

      }

      otherControl.valueChanges.subscribe(() => {

        thisControl.updateValueAndValidity();

      });

    }


    if (!otherControl) {

      return null;

    }


    if (otherControl.value !== thisControl.value) {

      return {

        matchOther: true

      };

    }


    return null;


  }


}

用法

这是将其与反应形式一起使用的方法:


private constructForm () {

  this.form = this.formBuilder.group({

    email: ['', [

      Validators.required,

      Validators.email

    ]],

    password: ['', Validators.required],

    repeatPassword: ['', [

      Validators.required,

      matchOtherValidator('password')

    ]]

  });

}

在此处可以找到更多最新的验证器:moebius-mlm / ng-validators。


查看完整回答
反对 回复 2019-11-06

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信