ошибка в сочетании с пользовательским компонентом управления формой - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь создать пользовательский MatFormFieldControl, который также реализует ControlValueAccessor.

Я хотел бы начать с известного варианта использования: форма пароля.

План: создать формуполе, которое получает единственную строку, но имеет свою собственную форму, которая добавляет валидацию к полю verifyPassword.

Я создал StackBlitz с работающей реализацией .

Каждый раз, когда вызывается переменная errorState, я проверяю, есть ли несоответствие между этими двумя полями, и обновляю ошибки в ngControl, чтобы они могли отображаться снаружи.

Состояние ошибки сначала отображается правильно,но если вы сопоставляете пароли, а потом снова не совпадаете, выдается эта ошибка:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: null'. Current value: 'ngIf: [object Object]'.

Я не могу найти много документации по этому вопросу в Интернете, и я не уверен, когда это правильное место длядобавить ошибку к объекту ошибок

Кто-нибудь знает, как мне избежать этой ошибки?

заранее спасибо

get errorState() {
  const missmatch = this.weightForm.value.password !== this.weightForm.value.confirmPassword;

  if (missmatch) {
    this.ngControl.control.setErrors({ missmatch }, { emitEvent: false });
  }

  return (this.ngControl.errors !== null || missmatch) && !!this.ngControl.touched;
}

Идея состоит в том, чтобы создать «разделение интересов», если внешняя форма не знает о verifyPassword, поскольку это скорее поле «Проверка» вместо поля «данные», если это имеет смысл.

Другим примером такого разделения интересов является наличие редактора кода в качестве поля формы, в котором проверки редактора кода отражаются снаружи, не подвергая редактор кода внешнему виду.

1 Ответ

0 голосов
/ 20 февраля 2019

тестируя ваш пример StackBlitz, я видел, что удаление * ngIf в app.component на mat-error решает проблему, оставляя неизменной «функцию сообщения об ошибках» при вводе формы, я не знаю, может ли это решить вашупроблема на вашем реальном сайте, но я думаю, что стоит попробовать.

Но что я действительно рекомендую вам для такого рода работы (проверка соответствия пароля), так это полагаться на средства проверки угловой формы (здесь документация формы: https://angular.io/guide/form-validation) этот подход более безопасен, потому что вам не нужно принудительно проверять ошибки с помощью переменных, но эта форма сама по себе понимает, является ли поле недействительным.

Стандарт не существуетвалидаторы для проверки того, что 2 поля содержат один и тот же текст, но вы можете создать свой собственный валидатор, который делает то, что вы хотите.

Если это может быть полезно, я поделюсь синтаксисом специального валидатора, который я обычно использую для пароляпроверьте (только как след, наверняка вы должны изменить что-то, чтобы это работало):

export function mismatchValidator(): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} | null => {
        if (control.parent) {
            if (control.parent.get('password').value !== control.parent.get('password_confirmation').value) {
                return {mismatch: true};
            } else {
                return null;
            }
        } else {
            return null;
        }
    };
}

Другая информация о том, какдля реализации контроллера формы, валидаторы и пользовательские валидаторы можно найти на сайте Angular.

Вот интересная статья о вашей проблеме, может быть, она поможет вам понять, где ваша проблемаесли вы решите не внедрять валидаторы формы.

...