Сообщения об ошибках проверки формы Angular2
Я новичок в Angular и JavaScript в целом, я пытаюсь добавить сообщения, когда пользовательский ввод неправильный с использованием библиотеки Materialize (атрибут data-error). Так что мой HTML-компонент выглядит так:
<input
type="text"
id="username"
formControlName="username"
[class.valid]="username?.valid && username.dirty"
[class.invalid]="!username?.valid && username.dirty && !username.pending"
>
<label for="username"
data-error="ERROR_MESSAGE" // <-- this is what I need to work
>Username</label>
Я хочу изменить атрибут data-error в зависимости от присутствующей ошибки. Прямо сейчас он напечатает "ERROR_MESSAGE" при любой ошибке. Я попытался написать функцию и связать ее с [attr.data-error] следующим образом:
displayUsernameErrorMessage() {
let message = '';
let usernameError = this.username.errors;
if(usernameError.pattern){
message = "Invalid Username"
console.log(usernameError);
}
else {
return null;
}
}
Я думаю, что я делаю действительно плохую работу с этим, функция записывается как 10 раз в консоли, и это плохое решение. Любые идеи о том, как заставить его работать лучше, приветствуются!
РЕДАКТИРОВАТЬ 1: Дополнительная информация о том, что я хочу отображать различные сообщения в зависимости от ошибки. Поэтому, если я получаю сообщение об ошибке из Validator.pattern - я хочу, чтобы сообщение было чем-то вроде "Неверное имя пользователя" или если оно из Validators.required - "Пожалуйста, введите имя пользователя", что-то вроде этого.
2 ответа
Мне нужно было сделать что-то подобное, поэтому я написал директиву, которую можно <label>
элементы.
В вашем примере это будет выглядеть так:
<label for="username" errorMessageForFormControl>Username</label>
<input required id="username" formControlName="username">
Я хотел избежать повторения имени элемента управления дважды, поэтому директива смотрит на значение for
атрибут и находит управление от этого. Если ваш FormControls и <input>
Полевые идентификаторы не совпадают, вы можете установить его самостоятельно.
<label for="somethingDifferent" errorMessageForFormControl="username">Username</label>
<input required id="somethingDifferent" formControlName="username">
Директива в итоге выглядела так:
import { Directive, Host, HostBinding, Input, Optional, OnInit, SkipSelf } from '@angular/core';
import { AbstractControl, ControlContainer } from '@angular/forms';
@Directive({
selector: '[errorMessageForFormControl]'
})
export class errorMessageDirective implements OnInit {
@HostBinding('class.validation-error') validationErrorCssClass = false;
@HostBinding('attr.data-error') errorMessage: string = null;
@Input() public errorMessageForFormControl: string;
@Input() public for: string;
private ctrl: AbstractControl = null;
constructor(
@Optional() @Host() @SkipSelf()
private controlContainer: ControlContainer
) { }
public ngOnInit(): void {
if (!this.controlContainer) {
return;
}
const formControlName = this.errorMessageForFormControl || this.for;
if (formControlName) {
this.ctrl = this.controlContainer.control.get(formControlName);
}
if (this.ctrl) {
this.ctrl.statusChanges.subscribe(statusText => {
if (statusText === 'INVALID') {
// invalid
const errors = this.ctrl.errors;
if (errors) {
const errKey = Object.keys(errors)[0];
const errVal = errors[errKey];
this.errorMessage = errVal === true ? errKey : errVal;
} else {
this.errorMessage = 'validation failed';
}
this.validationErrorCssClass = true;
} else {
// valid
this.errorMessage = null;
this.validationErrorCssClass = false;
}
});
}
}
}
И вы можете обратиться к атрибуту data-error в некоторых CSS
[data-error].validation-error::after {
color:red;
content: attr(data-error);
opacity: 0.8;
font-weight: bold;
font-style: italic;
font-size: 0.75em;
margin-right: 0.25em;
z-index: 99;
float: right;
transform: translateY(85%);
}
Вот как я это делаю (адаптировано к вашему примеру):
<form name="nameForm" [formGroup]="nameForm">
<fieldset>
<label for="username">Username</label>
<input
required
id="username"
formControlName="username"
>
<span
class="text-danger"
[hidden]="nameForm.controls.name.valid || itemForm.controls.name.pristine"
>
<small>{{'Please enter your name'}}</small>
</span>
</fieldset>
</form>
В вашем файле TS:
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
export class InputComponent {
public nameForm: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.nameForm = this.formBuilder.group({
username: new FormControl('', Validators.required),
});
}
//... codes..
}
Где вы можете настроить text-danger
в вашем CSS
(или любой альтернативный) файл