Наилучшая практика для реализации ошибок на стороне сервера с Mat-Error? - PullRequest
0 голосов
/ 25 июня 2018

Моя валидация и даже пользовательская валидация работают нормально с mat-error и реактивными формами, однако я попытался интуитивно реализовать свои ошибки на стороне сервера и оказался в беспорядке.

Мои ошибки на стороне сервера реализуются с помощью пользовательских валидаторов, которые проверяют наличие отклика на ошибки экспресс-валидатора, хранящегося в this.serverErrors.

Проблема, которая возникает, заключается в том, что я хочу, чтобы ошибка удалялась при обновлении значений или всей формы, чтобы можно было отключить кнопку отправки (это необязательная, но желаемая функция)

Я также использую несколько ошибок mat для каждого элемента управления через ngIfs.

Может кто-нибудь указать мне правильное направление для обработки ошибок на стороне сервера, предпочтительно с использованием mat-ошибок для отображения?

Спасибо.

export class ServerForm implements OnInit {

public serverErrors;
public form: FormGroup;

constructor(
  private formBuilder: FormBuilder,
  private routing: Router
) {}

ngOnInit() {
  this.form.valueChanges.subscribe(changes => {
    if (this.hasErrors()) {

      // For each error, check if expiryField values are outdated mandating error reset.
      Object.keys(this.serverErrors).forEach(error => {
        let serverError = this.serverErrors[error];
        // If error outdated, remove and reset validation.
        if (this.checkServerErrorOutdated(serverError)) {
          // Remove may only remove error text but control may still be invalid.
          this.removeServerError(error);
          this.triggerControlValidation(serverError.control);
        }
      });
    }
  });
}

checkServerErrorOutdated(serverError) {
  let outdated = false;
  // Default check to param, replace with expiry fields if exist.
  let expiryChecks = [ serverError.param ];
  if ('expiryFields' in serverError) {
    expiryChecks = serverError.expiryFields;
  }

  // For each expiry field check if a value has updated, thus expiring the error.
  expiryChecks.forEach(check => {
    let invalidValue = serverError.invalidValues[check];
    let currentValue = serverError.control.parent.value[check];
    if (currentValue !== invalidValue) { outdated = true; }
  });

  return outdated;
}

triggerControlValidation(control) {
  control.markAsTouched();       
  control.updateValueAndValidity();
}

triggerValidation() {
  Object.keys(this.form.controls).forEach(field => {
    let control = this.form.get(field);            
    this.triggerControlValidation(control);
  });
}

serverErrorValidator(errorKeyCode, errorKey, expiryFields?): ValidatorFn  {
  // May need to add server error keys to class property...
  return (control: AbstractControl): {[ key: string ]: any} | null => {
    let value = control.value;
    let error = {}; error[errorKeyCode] = value;
    let serverError = this.getServerError(errorKey);

    if (serverError) {
      // Add form values and control to error.
      serverError.invalidValues = control.parent.value;
      serverError.control = control;

      // Add fields which trigger error expiration to error.
      if (expiryFields) {
        serverError.expiryFields = expiryFields
      }
    }

    return serverError ? error : null;
  };
}

removeServerError(type) {
  if (type in this.serverErrors)
    delete this.serverErrors[type];
}

clearServerErrors() {
  Object.keys(this.serverErrors).forEach(field => {
    this.removeServerError(field);
  });
}

getServerErrorMsg(type) {
  let error = this.getServerError(type);
  return error ? error.msg : null;
}

getServerError(type) {
  let error = null;
  if (this.hasErrors() && type in this.serverErrors) {
    error = this.serverErrors[type];
  }

  return error ? error : null;
}

hasErrors() {
  return Boolean(this.serverErrors);
}

handleErrors(response) {
  if ('errors' in response) {
    this.serverErrors = response.errors;
  } else {
    this.clearServerErrors();
  }
}
}

1 Ответ

0 голосов
/ 26 июня 2018

Код, который я добавил к своему ответу, достигает того, чего я хотел.

  • Отображение ошибок с сервера в компонентах mat-error.
  • Удалите стилевое отображение ошибки и сообщение об ошибке при обновлении значения.
  • Функция вместе с отключенной кнопкой отправки из-за неверной формы.

Проблемы, с которыми я столкнулся, были связаны с поиском места, в которое можно зацепиться для повторной проверки, но не для немедленного устранения ошибки в valueChange, поскольку генератор событий valueChanges срабатывает слишком часто (даже для отправки / нажатия кнопки).

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