【问题标题】:Angular 6 reactive form validation not working with custom validatorAngular 6 反应式表单验证不适用于自定义验证器
【发布时间】:2019-03-08 21:56:01
【问题描述】:

所以我创建了一个自定义验证器来验证“新密码”字段和“确认密码”字段是否匹配。在组件级别上,它工作得很好。错误消息仅在两个输入不匹配时显示。

问题是,我禁用提交按钮,直到表单有效,但是当我使用这个自定义验证器时,整个表单永远不会通过验证。填写for表单时,所有组件验证通过,但表单验证不通过。

我在这里错过了什么?

自定义验证器代码如下所示:

import {FormGroup, ValidationErrors, ValidatorFn} from "@angular/forms";

export const matchingInputsValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
  let pass = control.get('NewPassword').value;
  let confirmPass = control.get('ConfirmPassword').value;
  return pass === confirmPass ? { matchingInputs: true } : { matchingInputs: false };
};

我将自定义验证器导入到我的组件中,并在组件中声明我的表单控件,如下所示:

expiredPasswordForm: FormGroup;
oldPassword = new FormControl('', Validators.compose([Validators.required, Validators.minLength(4)]));
newPassword = new FormControl('', Validators.compose([Validators.required, Validators.minLength(4)]));
confirmPassword = new FormControl('', Validators.compose([Validators.required, Validators.minLength(4)]));

在我的 ngOnInit() 生命周期钩子中,我创建了这样的表单组:

this.expiredPasswordForm = this.fb.group({
      'OldPassword': this.oldPassword,
      'NewPassword': this.newPassword,
      'ConfirmPassword': this.confirmPassword
    }, { validator: matchingInputsValidator});

我的表单 HTML 如下所示:

<form [formGroup]="expiredPasswordForm" ngNoForm action="" method="post" class="form-horizontal">

        <label for="oldPassword" class="col-sm-4 col-md-6 col-lg-6 col-xl-6 control-label" translate>Old Password</label>
        <input [formControl]="oldPassword" type="password" class="form-control" id="oldPassword"
               placeholder="Old Password" name="OldPassword" [ngClass]="{'is-invalid':oldPassword.invalid && (oldPassword.dirty || oldPassword.touched)}">
        <div *ngIf="oldPassword.invalid && (oldPassword.dirty || oldPassword.touched)" class="invalid-feedback">
          <span *ngIf="oldPassword.errors.required">Old Password is required</span>
        </div>

        <label for="newPassword" class="col-sm-4 col-md-6 col-lg-6 col-xl-6 control-label mt-2" translate>New Password</label>
        <input [formControl]="newPassword" type="password" class="form-control" id="newPassword"
               placeholder="New Password" name="NewPassword" [ngClass]="{'is-invalid':newPassword.invalid && (newPassword.dirty || newPassword.touched)}">
        <div *ngIf="newPassword.invalid && (newPassword.dirty || newPassword.touched)" class="invalid-feedback">
          <span *ngIf="newPassword.errors.required">A new password is required</span>
        </div>

        <label for="confirmPassword" class="col-sm-4 col-md-6 col-lg-6 col-xl-6 control-label mt-2" translate>Confirm Password</label>
        <input [formControl]="confirmPassword" type="password" class="form-control" id="confirmPassword"
               placeholder="Confirm Password" name="ConfirmPassword" [ngClass]="{'is-invalid':confirmPassword.invalid && (confirmPassword.dirty || confirmPassword.touched)}">
        <div *ngIf="confirmPassword.invalid && (confirmPassword.dirty || confirmPassword.touched)" class="invalid-feedback">
          <span *ngIf="confirmPassword.errors.required">You must confirm your new password!</span>
        </div>
        <div *ngIf="!expiredPasswordForm.errors?.matchingInputs">
          <span class="form-error-message">Passwords do not match!</span>
        </div>

        <div class="text-center">
          <button [disabled]="!expiredPasswordForm.valid" type="submit" class="btn btn-primary mt-4 mb-2">Update Password</button>
        </div>

      </form>

我希望这是足够的信息。为什么这适用于组件级别,但不适用于表单级别?提前谢谢!

【问题讨论】:

  • 我创建了许多异步验证器,通常当出现验证错误时我返回{ matchingInputs: true },否则我返回null。不确定它是否可以帮助你。

标签: javascript html angular angular-reactive-forms angular2-form-validation


【解决方案1】:

问题在于您的自定义验证器。

您可能已经弄清楚了,因为它是唯一设置在FormGroup 级别而不是FormControl 级别的验证器

验证器返回的对象是ValidationErrors 类型,它是一个包含键/值对的对象。对于每一对,键代表错误的名称,值代表关联的数据(例如要显示的详细信息)。

所以如果你想让你的验证器不返回任何错误,你必须什么都不返回:

import {FormGroup, ValidationErrors, ValidatorFn} from "@angular/forms";

export const matchingInputsValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
   let pass = control.get('NewPassword').value;
   let confirmPass = control.get('ConfirmPassword').value;
   return pass === confirmPass ? null : { matchingInputs: false };
}

【讨论】:

  • 啊,我明白了。是的,我认为它与我的自定义验证器有关,因为当我删除它时,它工作正常。我只是不知道我必须什么都不传回去。我以为它正在检查我传回的对象的值。非常感谢!!
猜你喜欢
  • 2019-05-20
  • 2020-01-13
  • 2021-11-01
  • 2019-01-26
  • 2019-01-13
  • 1970-01-01
  • 2019-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多