Угловой пользовательский валидатор для реактивной формы md-ошибка не отображается

Я не могу вывести *ngIf, если пароли не совпадают.

<md-form-field>
    <input mdInput placeholder="Repeat password" type="password" formControlName="repeat">
    <md-error *ngIf="form.controls['repeat'].errors?.required">Field required</md-error>
    <md-error *ngIf="form.errors?.matchingPasswords">passwords don't match</md-error>
</md-form-field>

Вот мой конструктор

  constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group({
      username:
      ['',
        Validators.compose([
          Validators.required,
          Validators.minLength(3),
          Validators.maxLength(30),
          this.validateUsername,
          this.validateUsernameAvailability
        ])
      ],
      email:
      ['',
        Validators.compose([
          Validators.required,
          Validators.maxLength(30),
          this.validateEmail
        ])
      ],
      password:
      ['',
        Validators.compose([
          Validators.required,
          Validators.minLength(8),
          Validators.maxLength(30),
          this.validatePassword
        ])
      ],
      repeat: ['',
        Validators.compose([
          Validators.required
        ])
      ]
    }, {validator: this.matchingPasswords('password', 'repeat')});
  }

  matchingPasswords(password, repeat) {
    return (group: FormGroup) => {
      // Check if both fields are the same
      if (group.controls[password].value === group.controls[repeat].value) {
        return null; // Return as a match
      } else {
        return { 'matchingPasswords': true }; // Return as error: do not match
      }
    };
  }

Вот скриншот

@EDIT Использование простого <span> вместо <md-error>, похоже, исправляет это.

<span *ngIf="form.errors?.matchingPasswords">passwords don't match</span>

Но почему <md-error> не появляется?


person Dawid    schedule 29.09.2017    source источник


Ответы (1)


Похоже, это «ошибка' это требует обходного пути.

md-error внутри md-form-field просто проверяет этот конкретный ввод, не принимая во внимание любые другие вводы. Поэтому, если вы переместите это за пределы md-form-field, оно будет проверено, но, конечно, в этом случае css будет испорчен. Исправление состоит в том, чтобы вместо этого использовать md-hint и просто изменить его с помощью css для эмуляции md-error:

<md-hint *ngIf="form.errors?.matchingPasswords">passwords don't match</md-hint>

Просто чтобы добавить его туда, вы можете пропустить пользовательский валидатор и использовать Пользовательское средство сопоставления ошибок примерно так:

myErrorStateMatcher(control: FormControl): boolean {
  if(control.parent.controls.password.value === control.value) {
    control.setErrors(null)
    return false;
  }
  else {
    control.setErrors({notSame:true})
    return true;
  }
}

в шаблоне:

<input mdInput formControlName="repeat" [errorStateMatcher]="myErrorStateMatcher">

ДЕМО

Но с этим вы действительно не можете контролировать, когда это уволено. Хотя с кодом, который у вас есть в настоящее время, ваш пользовательский валидатор также запускается всякий раз, когда происходит любое изменение формы. При этом ознакомьтесь с примечаниями ниже.


Примечания:

Если использовать md-hint, я бы поместил password и repeat во вложенную группу форм и применил настраиваемый валидатор к этой вложенной группе форм, чтобы он срабатывал только тогда, когда происходят изменения в любом из этих двух элементов управления формой.

Что касается элемента управления формы repeat, я не вижу необходимости использовать какую-либо другую проверку, кроме как проверять, соответствует ли он полю password.

person AJT82    schedule 30.09.2017