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();
Это решение.