Angular Материал - показать матовую ошибку при нажатии кнопки

Я пытаюсь выполнить проверку с помощью <mat-for-field> и <mat-error>. Это отлично работает, когда пользовательские вкладки выходят из ввода без заполнения. Но как заставить эту ошибку показывать, когда я нажимаю кнопку? Я не использую submit. Также, используя шаблонные формы.

Это мой код:

HTML:

<mat-form-field>
    <input matInput placeholder="Due Date" name="dueDate" [(ngModel)]="dueDate" [formControl]="dueDateValidator" required>
    <mat-error *ngIf="dueDateValidator.invalid">Due Date is required for Tasks</mat-error>
</mat-form-field>

TS:

dueDateValidator: FormControl = new FormControl('', [Validators.required]);

Ответ 1

Посмотрите, как использовать форму с пользовательским ErrorStateMatcher

Если вы хотите переопределить это поведение (например, чтобы показать ошибку, как только недопустимый элемент управления загрязнен или когда родительская группа форм недопустима), вы можете использовать свойство errorStateMatcher в matInput. Свойство принимает экземпляр объекта ErrorStateMatcher. ErrorStateMatcher должен реализовать один метод isErrorState, который принимает FormControl для этого matInput, а также родительскую форму и возвращает логическое значение, указывающее, должны ли отображаться ошибки. (true указывает, что они должны быть показаны, и false указывает, что они не должны.)

Я бы сделал отдельный файл, такой как default.error-matcher.ts

/** Error when invalid control is dirty or touched*/
export class MyErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return !!(control && control.invalid && (control.dirty || control.touched));
  }
}

Затем в файле TS добавьте:

matcher = new MyErrorStateMatcher();

Затем измените вход для использования matcher:

<mat-form-field>
    <input matInput placeholder="Due Date" name="dueDate" [(ngModel)]="dueDate" [formControl]="dueDateValidator" [errorStateMatcher]="matcher" required>
    <mat-error *ngIf="dueDateValidator.invalid">Due Date is required for Tasks</mat-error>
</mat-form-field>

Ответ 2

Так как вы хотите показать ошибку коврика при нажатии кнопки, попробуйте следующее: Для версии Angular6:

1). import below:
    import { FormControl, FormBuilder, FormGroup } from '@angular/forms';

2). declare form control in .ts file:
    nameControl = new FormControl('');

3). put control in html:
    <mat-form-field  style="width: 100%" floatPlaceholder="never">
      <input matInput placeholder="your placeholder text" [formControl]="nameControl" 
        required/>
      <mat-error *ngIf="nameControl.errors?.required">name is required</mat-error>
    </mat-form-field>

3). on button click:
    this.nameControl.markAsTouched();

Важно проверить, как вы используете элемент управления формы, ".markAsTouched()" в пункте 3 покажет ошибку мата для соответствующего элемента управления формы.

Ответ 3

Это работает для меня. :) При нажатии кнопки:

this.nameControl.markAsTouched();

Ответ 4

Основываясь на публикации Кайла Пфромера, я нашел свое решение (к той же проблеме):

В файле TS я добавил StateMatcher после того, как нашел неправильную форму, например.

if (this.myFormGroup.invalid) {
  this.matcher = new MyErrorStateMatcher();
  return;
}

В классе MyErrorStateMatcher я изменился следующим образом:

    return !!(control && control.invalid);

Меня смущает, что Angular Material все равно не обнаруживает ошибку.

Ответ 5

Вы также можете легко вызвать функцию AbstractControl.updateValueAndValidity() при нажатии кнопки. Это снова запустит процесс проверки на соответствующем ForControl и покажет ошибки, если они есть (на основе ваших Validators).

Итак, в вашем примере:

    checkForErrorsOnButtonClick(): void {
      dueDateValidator.updateValueAndValidity();
    }

Ответ 6

Я опоздал на вечеринку, но более простой способ вызвать проверку:

Object.keys(this.form.controls).forEach(field => { 
   const control = this.form.get(field);           
   control.markAsTouched({ onlySelf: true });      
});

Ответ 7

В Angular 8 появился новый метод форм: markAllAsTouched();

Это пометит элемент управления/форму и ВСЕХ ДЕСКЕНДАНТОВ как затронутые !!!

Так:

this.form.markAllAsTouched();

Это решение.