Как добавить валидацию на реактивную форму?angular-35

Валидация в реактивных формах Angular предоставляет мощные и гибкие возможности для проверки пользовательского ввода. Рассмотрим различные подходы к добавлению валидации.

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

Angular предоставляет набор встроенных валидаторов в классе Validators:

import { FormGroup, FormControl, Validators } from '@angular/forms';

this.userForm = new FormGroup({
  username: new FormControl('', [
    Validators.required,
    Validators.minLength(5),
    Validators.maxLength(20)
  ]),
  email: new FormControl('', [
    Validators.required,
    Validators.email
  ]),
  age: new FormControl('', [
    Validators.min(18),
    Validators.max(99)
  ])
});

Доступные встроенные валидаторы:

  • Validators.required - обязательное поле
  • Validators.minLength(minLength) - минимальная длина
  • Validators.maxLength(maxLength) - максимальная длина
  • Validators.pattern(pattern) - проверка по регулярному выражению
  • Validators.min(min) - минимальное числовое значение
  • Validators.max(max) - максимальное числовое значение
  • Validators.email - проверка email формата

2. Кастомные валидаторы

Когда встроенных валидаторов недостаточно, можно создать собственные:

2.1. Валидатор как функция

function forbiddenNameValidator(nameRe: RegExp) {
  return (control: FormControl) => {
    const forbidden = nameRe.test(control.value);
    return forbidden ? { forbiddenName: { value: control.value } } : null;
  };
}

// Использование:
this.userForm = new FormGroup({
  username: new FormControl('', [
    Validators.required,
    forbiddenNameValidator(/admin/i)
  ])
});

2.2. Валидатор как класс

import { AbstractControl, ValidationErrors } from '@angular/forms';

export class PasswordValidator {
  static strong(control: AbstractControl): ValidationErrors | null {
    const value = control.value;
    if (!value) return null;

    const hasUpperCase = /[A-Z]/.test(value);
    const hasLowerCase = /[a-z]/.test(value);
    const hasNumeric = /[0-9]/.test(value);
    const hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(value);

    const valid = hasUpperCase && hasLowerCase && hasNumeric && hasSpecial;
    return !valid ? { strongPassword: true } : null;
  }
}

// Использование:
password: new FormControl('', [
  Validators.required,
  PasswordValidator.strong
])

3. Кросс-полевая валидация

Для валидации, которая зависит от нескольких полей формы:

this.userForm = new FormGroup({
  password: new FormControl('', Validators.required),
  confirmPassword: new FormControl('', Validators.required)
}, { validators: this.passwordMatchValidator });

passwordMatchValidator(form: FormGroup): ValidationErrors | null {
  return form.get('password').value === form.get('confirmPassword').value
    ? null
    : { mismatch: true };
}

4. Асинхронные валидаторы

Для валидации, требующей асинхронных операций (например, проверка на сервере):

username: new FormControl('', {
  validators: [Validators.required],
  asyncValidators: [this.usernameValidator.checkUsername.bind(this.usernameValidator)],
  updateOn: 'blur'
})

5. Отображение ошибок валидации

В шаблоне можно отображать сообщения об ошибках:

<form [formGroup]="userForm">
  <input formControlName="username">
  <div *ngIf="userForm.get('username').errors && userForm.get('username').touched">
    <div *ngIf="userForm.get('username').errors.required">Username is required</div>
    <div *ngIf="userForm.get('username').errors.minlength">
      Username must be at least 5 characters
    </div>
    <div *ngIf="userForm.get('username').errors.forbiddenName">
      This username is forbidden
    </div>
  </div>
</form>

6. Динамическое изменение валидаторов

Валидаторы можно добавлять/удалять динамически:

// Добавить валидатор
this.userForm.get('email').addValidators(Validators.email);

// Удалить все валидаторы
this.userForm.get('email').clearValidators();

// Обновить валидацию
this.userForm.get('email').updateValueAndValidity();

7. Валидация FormArray

Пример валидации массива элементов:

this.userForm = new FormGroup({
  skills: new FormArray([], [Validators.required, Validators.minLength(3)])
});

addSkill() {
  this.skills.push(new FormControl('', Validators.required));
}

Резюмируем

Angular предоставляет мощные инструменты для валидации реактивных форм - от простых встроенных валидаторов до сложных кастомных и асинхронных решений. Правильно реализованная валидация улучшает UX и обеспечивает целостность данных. Для сложных сценариев можно комбинировать несколько подходов валидации.