обработка с несколькими ошибками мат - PullRequest
0 голосов
/ 16 января 2020

У меня есть моя обработка ошибок для мат-ввода, подобная этой

      <mat-form-field>
        <input formControlName="title" matInput placeholder="Title*" />
        <mat-error *ngIf="addNewForm.get('title').errors?.required">
          Can not be empty
        </mat-error>
        <mat-error *ngIf="addNewForm.get('title').errors?.minlength">
          Min length is 1 character
        </mat-error>
        <mat-error *ngIf="addNewForm.get('title').errors?.maxlength">
          Max length is 255 characters
        </mat-error>
      </mat-form-field>

      <mat-form-field>
        <input formControlName="name" matInput placeholder="Name*" />
        <mat-error *ngIf="addNewForm.get('name').errors?.required">
          Can not be empty
        </mat-error>
        <mat-error *ngIf="addNewForm.get('name').errors?.minlength">
          Min length is 1 character
        </mat-error>
        <mat-error *ngIf="addNewForm.get('name').errors?.maxlength">
          Max length is 255 characters
        </mat-error>
      </mat-form-field>

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

      <mat-form-field>
        <input formControlName="title" matInput placeholder="Title*" />
        <mat-error>{{ someError }}</mat-error>
      </mat-form-field>

      <mat-form-field>
        <input formControlName="name" matInput placeholder="Name*" />
        <mat-error>{{ someError }}</mat-error>
      </mat-form-field>

Вот компонент

this.addNewUserForm = this.formBuilder.group({
      title: [
        "",
        [
          Validators.required,
          Validators.minLength(1),
          Validators.maxLength(255),
          noWhitespaceValidator
        ]
      ],
      name: [
        "",
        [
          Validators.required,
          Validators.minLength(4),
          Validators.maxLength(255),
          noWhitespaceValidator
        ]
      ]
    });

Ответы [ 2 ]

1 голос
/ 16 января 2020

Вот один из подходов:

Прослушайте statusChanges наблюдаемого вашего FormControl экземпляра и, когда он издаст, получите свою первую ошибку.

const titleCtrl = this.addNewUserForm.get('title');

const titleErr$ = titleCtrl.statusChanges
  .pipe(
   filter(status => status === 'INVALID'),
   map(() => {
    if (!titleCtrl.errors) {
      return null; 
    }   

    // Returning the first error
    for (const errName in titleCtrl.errors) {
       return titleCtrl.errors[errName];
     }
   }),
   filter(err => !!err)
  )

Теперь это зависит в вашем случае использования.

Если вам нужно использовать свою ошибку только один раз в шаблоне, вы можете использовать asyn c pipe .

<mat-form-field>
    <input formControlName="title" matInput placeholder="Title*" />
    <mat-error>{{ titleErr$ | async }}</mat-error>
</mat-form-field>

Если вам нужно использовать ошибку в нескольких местах или если вам нужно выполнить один и тот же лог c для нескольких FormControl с, вы можете либо подписаться в компоненте ( imperative way), либо найти способ объединить все ошибки и сохранить подписку в представлении ( реактивный способ).

Имейте в виду, что если вы подписываетесь в классе компонентов, вы придется отписаться.

1 голос
/ 16 января 2020

Вы можете написать функцию получения, которая просто возвращает сообщение об ошибке. Например:

get errorMessage(): string {
   const form: FormControl = (this.addNewUserForm.get('title') as FormControl);
   return form.hasError('required') ?
     'Required error message' :
     form.hasError('maxlength') ?
     'Max length error' : 
     form.hasError('minlength') ?
     'Min length error' :
     form.hasError('nowhitespaceerror') ?
     'No white space error' : '';
}

После этого вы просто используете этот метод как переменную в шаблоне:

<mat-error>{{ errorMessage }}</mat-error>

Или простое решение на основе этого примера: здесь .

export class InputErrorExample {
  constructor(private formBuilder: FormBuilder) {}

  errorMessages = {
    maxlength: 'max',
    minlength: 'min',
    email: 'email'
  };

  addNewUserForm = this.formBuilder.group({
      title: [
        "",
        [
          Validators.required,
          Validators.minLength(1),
          Validators.maxLength(255),
          Validators.email
          // noWhitespaceValidator
        ]
      ]
    });

  errors(ctrl: FormControl): string[] {
    return ctrl.errors ? Object.keys(ctrl.errors) : [];
  }
}
<form class="example-form">
  <mat-form-field class="example-full-width">
    <input matInput placeholder="Email" [formControl]="addNewUserForm.get('title')"
           [errorStateMatcher]="matcher">
    <mat-hint>Errors appear instantly!</mat-hint>
    <mat-error>
      <ng-container *ngFor="let error of errors(addNewUserForm.get('title'))">
        {{ errorMessages[error] }} <br>
      </ng-container>
    </mat-error>
  </mat-form-field>
</form>
...