Angular2中的交叉字段验证

时间:2016-02-15 15:56:37

标签: javascript validation angular

我正在构建一个Angular2客户端应用程序。我目前正在研究成员资格组件,并将客户端组件与MVC6 vNext Identity v3集成。我已经编写了自定义Angular2密码验证器,如下所示:

Results.xls
I_30_2_02_02_1.csv      7   239 7   174 7   458 7   156 7   163

这项工作很棒,而且我很喜欢Angular2,但现在我正在尝试编写一个验证器来验证“确认密码”是否等于“密码”。为了做到这一点,我需要能够相对于另一个验证一个字段。我可以在组件级别轻松完成此操作,只需检查模糊,提交或其他任何方式,但这会绕过Angular2 ngForm验证系统。我非常想弄清楚如何为一个可以检查另一个字段的值的字段编写一个Angular2 Validator,方法是传入另一个字段的名称或者接近它的东西。这似乎应该是一种能力,因为这在几乎任何复杂的业务应用程序UI中都是必需的。

3 个答案:

答案 0 :(得分:28)

您需要将自定义验证程序分配给完整的表单组才能实现此目的。像这样:

this.form = this.fb.group({
  name:  ['', Validators.required],
  email: ['', Validators.required]
  matchingPasswords: this.fb.group({
    password:        ['', Validators.required],
    confirmPassword: ['', Validators.required]
  }, {validator: this.matchValidator})  <--------
});

这样您就可以访问该组的所有控件,而不仅仅是一个...这可以使用FormGroup的controls属性进行访问。触发验证时提供FormGroup。例如:

matchValidator(group: FormGroup) {
  var valid = false;

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

  if (valid) {
    return null;
  }

  return {
    mismatch: true
  };
}

有关详细信息,请参阅此问题:

答案 1 :(得分:13)

您还可以使用自定义指令验证程序来比较字段。

在你的HTML中:

<div>
    <label>Password</label>
    <input type="password" name="password" [ngModel]="user.password" 
        required #password="ngModel">
    <small [hidden]="password.valid || (password.pristine && !f.submitted)">
        Password is required
    </small>
</div>
<div>
    <label>Retype password</label>
    <input type="password" name="confirmPassword" [ngModel]="user.confirmPassword" 
        required validateEqual="password" #confirmPassword="ngModel">
    <small [hidden]="confirmPassword.valid ||  (confirmPassword.pristine && !f.submitted)">
        Password mismatch
    </small>
</div>

你的指示:

import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
    selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
    providers: [
        { provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
    ]
})
export class EqualValidator implements Validator {
    constructor( @Attribute('validateEqual') public validateEqual: string) {}

    validate(c: AbstractControl): { [key: string]: any } {
        // self value (e.g. retype password)
        let v = c.value;

        // control value (e.g. password)
        let e = c.root.get(this.validateEqual);

        // value not equal
        if (e && v !== e.value) return {
            validateEqual: false
        }
        return null;
    }
}

以下是plunkr中的完整解决方案:

https://plnkr.co/edit/KgjSTj7VqbWMnRdYZdxM?p=preview

答案 2 :(得分:4)

我自己没有这样做,但您可以使用两个密码字段创建ControlGroup并验证它。控件具有.valueChanges属性,这是一个可观察的属性,您可以将它们组合起来并检查那里的相等性。

Victor Savkin在this episode

中简要介绍了Angular Air的确切案例