Angular - Валидатор в FormGroup ломает отдельные валидаторы в FormControl - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть стандартная страница смены пароля, поэтому вы вводите свой старый пароль, затем новый и, наконец, повторяете новый.

На «new password» у меня есть несколько пользовательских валидаторов, и я нужно еще один, чтобы проверить, равен ли "new password" "old password".

Но, конечно, я не могу сделать это с FormControl, потому что у меня нет доступа к "old password "FormControl, поэтому мне нужно выполнить проверку на FormGroup.

Но что происходит, когда он проверяет эту часть на FormGroup, то внезапно все валидаторы на" new password "FormControl сработало !!

Есть ли причина?

 this.myForm = this.formBuilder.group(
      {
        oldPassword: [
          "",
          {
            validators: [Validators.required],
        ],
        newPassword: [
          "",
          Validators.compose([
            Validators.required,
            CustomValidators.patternValidator(/\d/, { hasNumber: true }),
            CustomValidators.patternValidator(/[A-Z]/, {
              hasCapitalCase: true,
            }),
            CustomValidators.patternValidator(/[a-z]/, { hasSmallCase: true }),
            CustomValidators.patternValidator(
              /[ !@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/,
              { hasSpecialCharacters: true }
            ),
            Validators.minLength(8),
          ]),
        ],
        confirmNewPassword: ["", Validators.compose([Validators.required])],
      },
      { validators: [CustomValidators.passwordMatchValidator] }
    );
  }

my Custom passwordMatchValidator:

static passwordMatchValidator(control: AbstractControl) {
    const password: string = control.get("newPassword").value; 
    const confirmPassword: string = control.get("confirmNewPassword").value; 
    const oldPassword: string = control.get("oldPassword").value;

    if (password !== confirmPassword) {
      control.get("confirmNewPassword").setErrors({ NoPassswordMatch: true });
    }

    if (password === oldPassword) {

   control.get("newPassword").setErrors({ OldPasswordMatch: true });
  }
  }

в принципе, если этот валидатор FormGroup вызывает ошибку "OldPasswordMatch" и вдруг все указанные c валидаторы на newPassword FormControl сработают, почему это так?

Я не могу поставить эту проверку на FormControl "new password", потому что он не имеет доступа к FormControl "old password"

1 Ответ

1 голос
/ 17 апреля 2020

не уверен, что вы говорите по поводу "запуска всех валидаторов", так как все они проверяются все время, но, тем не менее, вы неправильно внедряете валидатор на уровне группы. валидаторы не должны обращаться к элементам управления и устанавливать ошибки, они возвращают ноль или объект ошибки ... так как это валидатор на уровне группы, он должен быть похож на:

static passwordMatchValidator(control: AbstractControl) {
    const password: string = control.get("newPassword").value; 
    const confirmPassword: string = control.get("confirmNewPassword").value; 
    const oldPassword: string = control.get("oldPassword").value;

    let errors = null;

    if (password !== confirmPassword) {
      errors = { NoPassswordMatch: true };
    }

    if (password === oldPassword) {
      errors = Object.assign(errors || {}, { OldPasswordMatch: true });
    }

    return errors;
}

, тогда эта ошибка появится в группе , и вы должны принять это во внимание в шаблоне / запросах пользователя.

, чтобы ваши данные знали об ошибке с материалом angular, вы должны реализовать ErrorStateMatcher:

import {FormControl, FormGroupDirective, NgForm} from '@angular/forms';
import {ErrorStateMatcher} from '@angular/material/core';

export class GroupErrorStateMatcher implements ErrorStateMatcher {

  constructor(private checkError: string) {}

  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    const groupError = form && form.hasError(this.checkError);
    return !!(control && (control.invalid || groupError) && (control.dirty || control.touched));
  }
}

использовать в компоненте:

oldPasswordMatch =  new GroupErrorStateMatcher('OldPasswordMatch')
noPasswordMatch =  new GroupErrorStateMatcher('NoPassswordMatch')

, который вы подключаете к соответствующим входам:

<input matInput [errorStateMatcher]="oldPasswordMatch" formControlName="newPassword">

<input matInput [errorStateMatcher]="noPasswordMatch" formControlName="confirmNewPassword">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...