Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Проверка данных формы

Проверка (валидация) не даёт отправить форму с пустыми или неправильными данными и подсказывает пользователю, что исправить. В реактивных формах правила задаются в классе вместе с полями, а шаблон показывает сообщения.

Встроенные валидаторы

Правила передают вторым аргументом FormControl в массиве validators:

// src/app/post-form/post-form.ts
import { Component } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
 
@Component({
  selector: 'app-post-form',
  imports: [ReactiveFormsModule],
  templateUrl: './post-form.html',
})
export class PostForm {
  form = new FormGroup({
    title: new FormControl('', {
      nonNullable: true,
      validators: [Validators.required, Validators.minLength(5)],
    }),
    body: new FormControl('', {
      nonNullable: true,
      validators: [Validators.required],
    }),
  });
}

Заголовок обязателен и не короче пяти символов, текст обязателен.

ВалидаторПравило
Validators.requiredПоле не пустое
Validators.minLength(5)Не меньше 5 символов
Validators.maxLength(100)Не больше 100 символов
Validators.emailПохоже на адрес почты
Validators.min(1), Validators.max(10)Число в пределах
Validators.pattern(/^[a-z]+$/)Соответствует регулярному выражению

Сообщения об ошибках

У каждого поля есть свойства состояния. invalid — правило нарушено, touched — пользователь уже побывал в поле. Метод hasError() проверяет конкретное правило:

<!-- src/app/post-form/post-form.html -->
<form [formGroup]="form" (ngSubmit)="save()">
  <input formControlName="title" placeholder="Заголовок" />
 
  @let title = form.controls.title;
  @if (title.touched && title.hasError('required')) {
    <p class="error">Введите заголовок.</p>
  }
  @if (title.touched && title.hasError('minlength')) {
    <p class="error">Не короче 5 символов.</p>
  }
 
  <textarea formControlName="body" placeholder="Текст"></textarea>
  <button type="submit" [disabled]="form.invalid">Опубликовать</button>
</form>

Блок @let объявляет короткое имя прямо в шаблоне. Щёлкните в поле заголовка и уйдите из него — появится «Введите заголовок.». Наберите «Тест» — сообщение сменится на «Не короче 5 символов.». Кнопка остаётся заблокированной, пока форма неверна.

CSS-классы состояния

Angular сам добавляет полям классы ng-valid, ng-invalid, ng-touched, ng-dirty. Красная рамка у ошибочного поля делается без кода:

/* src/app/post-form/post-form.css */
input.ng-invalid.ng-touched,
textarea.ng-invalid.ng-touched {
  border: 1px solid crimson;
}

Проверка при отправке

Если кнопку не блокировать, проверьте форму в методе и подсветите все ошибки сразу:

// src/app/post-form/post-form.ts
save() {
  if (this.form.invalid) {
    this.form.markAllAsTouched();
    return;
  }
  console.log('Отправляем', this.form.getRawValue());
}

markAllAsTouched() помечает все поля как посещённые, и сообщения появляются у каждого неверного поля.

Свой валидатор

Валидатор — функция, которая получает поле и возвращает null, если всё в порядке, или объект с описанием ошибки:

// src/app/no-spam.ts
import { AbstractControl, ValidationErrors } from '@angular/forms';
 
export function noSpam(control: AbstractControl): ValidationErrors | null {
  const text = String(control.value).toLowerCase();
  return text.includes('casino') ? { spam: true } : null;
}

Подключите его как встроенный: validators: [Validators.required, noSpam], а в шаблоне проверяйте hasError('spam').

Частая ошибка

Показывать ошибки сразу при открытии формы. Пустое обязательное поле неверно с самого начала, и пользователь видит красный текст, ещё ничего не сделав. Добавляйте к условию touched или dirty, как в примере выше.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.