Сообщения об ошибках проверки формы 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 (или любой альтернативный) файл

Другие вопросы по тегам