Валидация в реактивных формах Angular предоставляет мощные и гибкие возможности для проверки пользовательского ввода. Рассмотрим различные подходы к добавлению валидации.
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 форматаКогда встроенных валидаторов недостаточно, можно создать собственные:
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)
])
});
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
])
Для валидации, которая зависит от нескольких полей формы:
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 };
}
Для валидации, требующей асинхронных операций (например, проверка на сервере):
username: new FormControl('', {
validators: [Validators.required],
asyncValidators: [this.usernameValidator.checkUsername.bind(this.usernameValidator)],
updateOn: 'blur'
})
В шаблоне можно отображать сообщения об ошибках:
<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>
Валидаторы можно добавлять/удалять динамически:
// Добавить валидатор
this.userForm.get('email').addValidators(Validators.email);
// Удалить все валидаторы
this.userForm.get('email').clearValidators();
// Обновить валидацию
this.userForm.get('email').updateValueAndValidity();
Пример валидации массива элементов:
this.userForm = new FormGroup({
skills: new FormArray([], [Validators.required, Validators.minLength(3)])
});
addSkill() {
this.skills.push(new FormControl('', Validators.required));
}
Angular предоставляет мощные инструменты для валидации реактивных форм - от простых встроенных валидаторов до сложных кастомных и асинхронных решений. Правильно реализованная валидация улучшает UX и обеспечивает целостность данных. Для сложных сценариев можно комбинировать несколько подходов валидации.