自定义密码匹配验证器在 angular5 中不起作用

问题描述 投票:0回答:3

我正在实现自定义验证器来匹配组件中的密码。

这是我的 component.ts 表单声明

this.addUserForm = new FormGroup({
  firstname: new FormControl('', [Validators.required]),
  lastname: new FormControl('', [Validators.required]),
  city: new FormControl(),
  address: new FormControl(),
  email: new FormControl('', [Validators.required, Validators.email]),
  password: new FormControl('', [Validators.required, Validators.minLength(6)]),
  confirm_password: new FormControl('', [Validators.required, ConfirmPasswordValidator.MatchPassword]),
  role: new FormControl('', [Validators.required]),
  phone: new FormControl(),
  companyCode: new FormControl(this.local_storage.getCurrentUser().companyCode, [Validators.required])
});

这是我的custom.validator.ts

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

export class ConfirmPasswordValidator {
static MatchPassword(control: AbstractControl) {
    let password = control.get('password').value;
    let confirmPassword = control.get('confirm_password').value;

    if (password != confirmPassword) {
        console.log('false')
        control.get('confirmPassword').setErrors({ ConfirmPassword: true });
    } else {
        return null
    }
  }
 }

这是我的component.html输入部分

 <label class="col-form-label">Password</label>
        <div class="form-group row">
          <div class="col-sm-10">
            <input type="password" class="form-control" formControlName="password">
            <div class="alert alert-danger" *ngIf="addUserForm.get('password').touched && addUserForm.get('password').invalid && addUserForm.get('password').errors.required">
              Password is required
            </div>
            <div class="alert alert-danger" *ngIf="addUserForm.get('password').touched && addUserForm.get('password').invalid && addUserForm.get('password').errors.minlength && !addUserForm.get('password').errors.required">
              Password length must be greater than 6
            </div>
          </div>
        </div>
       <div class="alert alert-danger" *ngIf="addUserForm.get('confirm_password').touched && addUserForm.get('confirm_password').invalid && addUserForm.get('confirm_password').errors.ConfirmPassword">
              Password deesn't match
          </div>

但它给出了这个错误

property 'value' of null TypeError: Cannot read property 'value' of null at ConfirmPasswordValidator.MatchPassword (user.validator.ts:5)
项目结构和目录非常复杂和巨大,这就是为什么不能共享所有组件和 html 代码。 我的代码有什么问题吗?

angular validation angular5 angular2-forms customvalidator
3个回答
1
投票

表单组验证器

更新

MatchPassword
以在表单组级别工作,因此您无需向
confirmPassword
控件添加客户验证器

static MatchPassword(control: AbstractControl) {
    let password = control.get('password').value;
    let confirmPassword = control.get('confirm_password').value;

    if (password != confirmPassword) {
      return { ConfirmPassword: true };
    } else {
        return null
    }
  }

并为 formGroup 验证器选项添加此验证器

{ validators: ConfirmPasswordValidator.MatchPassword }

stackblitz 演示 🚀🚀

表单控件验证器

如果你想给控件添加验证,那么控件参数将是确认密码控件,你需要使用parent来访问表单组并获取密码控件的值

this.form = fb.group({
  password: [null, [Validators.required]],
  confirm_password: [null, [Validators.required, MatchPassword]]
})

匹配密码验证器

function MatchPassword(control: AbstractControl) {
  let parent = control.parent
  if (parent) {
    let password = parent.get('password').value;
    let confirmPassword = control.value;

    if (password != confirmPassword) {
      return { ConfirmPassword: true };
    } else {
      return null
    }
  } else {
    return null;
  }

stackblitz 演示 🚀🚀


1
投票

您的代码存在几个问题。

首先:您将从名为“password”的控件中获取一个子控件,并从传递给验证器的控件中获取另一个名为“confirmPassword”的子表单控件。所以验证器应该验证的是一个包含这两个表单控件的

FormGroup
。但是您没有在表单组上设置此验证器。您正在表单控件上设置它
confirmPassword
。您需要在封闭的表单组上设置此验证器。

第二:验证器不应该修改它正在验证的控件。它的唯一责任是返回错误(如果没有错误则返回 null)。 Angular 将根据您返回的内容设置控件的有效性。所以它的代码应该是

static MatchPassword(control: AbstractControl) {
  const password = control.get('password').value;
  const confirmPassword = control.get('confirm_password').value;

  if (password != confirmPassword) {
    return { ConfirmPassword: true };
  } else {
    return null;
  }
}

或者,写得更简洁:

static MatchPassword(control: AbstractControl) {
  return control.get('password').value != control.get('confirm_password').value ? { ConfirmPassword: true } : null;
}

0
投票
`registerForm = new FormGroup({
username : new FormControl(),
password : new FormControl(),
confirmPassword : new FormControl(null,matchValues["password"])
);`

每次用户输入密码字段时,都会在确认密码中运行验证器

`registerForm.controls['password'].valueChanges.subscribe({
next: (_) =>
registerForm.controls['confirmPassword'].updateValueAndValidity(),
});`

验证器功能

matchValues(matchTo: string): ValidatorFn { return (control: AbstractControl) => { return control.value === control.parent?.get(matchTo)?.value ? null : { isMatching: true }; }; }

© www.soinside.com 2019 - 2024. All rights reserved.