如何使此密码匹配验证工作

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

我有这个代码来检查两个密码是否匹配,但是,它没有按预期工作。我已经尝试过在一些旧问题中看到的内容,但没有成功。

我的组件模板中有这个:

<form [formGroup]="passwordForm">

  <mat-form-field>
    <input #thePassword matInput [type]="hidePasswordButton ? 'password' : 'text'" [formControl]="password"
      (input)="onPasswordInput(thePassword.value)" />

    <mat-label>Enter Password</mat-label>

    <mat-error *ngIf="password.hasError('required')">
      Password is <strong>required</strong>
    </mat-error>

    <mat-error *ngIf="password.hasError('minlength')">
      Must have <strong>at least 8 characters.</strong>
    </mat-error>

    <button mat-icon-button matSuffix (click)="hidePasswordButton = !hidePasswordButton"
      [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hidePasswordButton">
      <mat-icon>{{ hidePasswordButton ? "visibility_off" : "visibility" }}</mat-icon>
    </button>
  </mat-form-field>

  <mat-form-field *ngIf="!isInputDisabled()">
    <input #ConfirmedPassword matInput [type]="hideConfirmedPasswordButton ? 'password' : 'text'"
      [formControl]="confirmedPassword" (input)="onConfirmedPasswordInput(ConfirmedPassword.value)" />

    <mat-label>Confirm Password</mat-label>

    <mat-error *ngIf="passwordForm.errors?.['mismatch']">
      Passwords <strong>don't match</strong>
    </mat-error>

    <mat-error *ngIf="confirmedPassword.hasError('required')">
      <strong>You must confirm your password</strong>
    </mat-error>

    <button mat-icon-button matSuffix (click)="hideConfirmedPasswordButton = !hideConfirmedPasswordButton"
      [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hideConfirmedPasswordButton">
      <mat-icon>{{ hideConfirmedPasswordButton ? "visibility_off" : "visibility" }}</mat-icon>
    </button>
  </mat-form-field>
</form>

那么ts文件是这样的:

import { matchingPasswords } from 'src/types/password-match-validator';

password = new FormControl('', [Validators.required, Validators.minLength(8), Validators.pattern(/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)/)]);

  confirmedPassword = new FormControl('', [Validators.required, Validators.minLength(8)]);

  passwordForm: FormGroup = new FormGroup({
    password: this.password,
    confirmedPassword: this.confirmedPassword
  },
    {
      validators: [matchingPasswords]
    });

matchingPasswords
验证器来自这个类:

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

export const matchingPasswords : ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
    const password = control.get('password');
    const confirmedPassword = control.get('confirmedPassword');
    return password 
           && confirmedPassword 
           && password.value !== confirmedPassword.value 
           ? { 'mismatch': true } 
           : null;
           
}

这种方法有点有效,如果我在密码输入中输入一些内容,说“Abcd1234”,然后在确认中输入一些随机内容,那么 mat-error 就会触发,但是,如果我在密码中输入类似“123456aA”的内容输入,然后在确认中输入类似“123456aB”的内容,即使两个密码不完全相同,也不会出现错误。至少它不让我提交表单,但我需要显示该错误消息。

我已经尝试过

this.fb.group
方法,但这也不起作用。

angular typescript angular-material angular-reactive-forms angular-validation
1个回答
2
投票

passwordForm.errors?.['mismatch']
错误的原因是由于
ErrorStateMatcher
的默认行为,当满足这些条件时会显示错误:

  1. 控制无效。
  2. 要么触摸控件,要么提交表单。

confirmedPassword
FormControl
需要显示除自身错误之外的错误,即来自 FormGroup 的“不匹配”错误。

您需要覆盖默认的

ErrorStateMatcher
行为才能解决问题。

  1. 创建自定义
    ErrorStateMatcher
export class ConfirmedPasswordErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(
    control: FormControl | null,
    form: FormGroupDirective | NgForm | null
  ): boolean {
    return !!(
      control &&
      (control.invalid || form?.errors?.['mismatch']) &&
      (control.dirty || control.touched || (form && form.submitted))
    );
  }
}
  1. 在组件中声明
    ConfirmedPasswordErrorStateMatcher
    实例。
confirmedPasswordErrorStateMatcher = new ConfirmedPasswordErrorStateMatcher();
  1. [errorStateMatcher]="confirmedPasswordErrorStateMatcher"
    添加到
    confirmedPassword
    控件。
<input
  #ConfirmedPassword
  matInput
  [type]="hideConfirmedPasswordButton ? 'password' : 'text'"
  [formControl]="confirmedPassword"
  (input)="onConfirmedPasswordInput(ConfirmedPassword.value)"
  [errorStateMatcher]="confirmedPasswordErrorStateMatcher"
/>

演示@StackBlitz

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