Статьи

Как создать пользовательские валидаторы в Angular

В этом посте мы узнаем, как создавать собственные валидаторы в Angular Reactive Forms. Если вы новичок в реактивных формах, узнайте, как создать свою первую угловую реактивную форму здесь .

Допустим, у нас есть форма входа, как показано в коде ниже. В настоящее время к элементам управления формы не прикреплены никакие проверки.

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null),
        password: new FormControl(null),
        age: new FormControl(null)
    });
}

Здесь мы используем  FormGroupдля создания реактивной формы. К шаблону компонента вы можете прикрепить,  loginForm как показано в коде ниже. При использовании привязки  formGroup свойства для свойства элемента HTML устанавливается значение,  loginForm а для  formControlName значения этих элементов управления устанавливается индивидуальное  FormControl свойство FormGroup.

Это даст вам реактивную форму в вашем заявлении:

Использование валидаторов

Angular предоставляет нам много полезных валидаторов, в том числе required , minLength , maxLength и pattern . Эти валидаторы являются частью класса Validators , который поставляется с пакетом @ angular / forms .

Предположим, вы хотите добавить обязательную проверку в элемент управления электронной почтой и  maxLength проверку в элемент управления паролем. Вот как вы это делаете:

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null)
    });
}

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

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

В шаблоне вы можете использовать валидаторы, чтобы показать или скрыть сообщение об ошибке. По сути, вы читаете,  formControl используя  get() метод, и проверяете, есть ли в нем ошибка или нет, используя  hasError() метод. Вы также проверяете, formControl прикоснулись ли  вы или нет, используя свойство touch.

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

Пользовательские валидаторы

Допустим, вы хотите, чтобы возраст был от 18 до 45 лет. Angular не дает нам подтверждения диапазона; поэтому для этого нам придется написать собственный валидатор.

В Angular создать собственный валидатор так же просто, как создать другую функцию. Единственное, что вам нужно иметь в виду, это то, что он принимает один входной параметр типа  AbstractControl и возвращает объект пары ключ-значение в случае сбоя проверки.

Давайте создадим собственный валидатор под названием ageRangeValidator , в котором пользователь сможет вводить возраст, только если он находится в заданном диапазоне.

Тип первого параметра  AbstractControl, так как он является базовым классом  FormControlFormArrayи FormGroup, и это позволяет считывать значение элемента управления , переданного в функцию валидатора. Пользовательский валидатор возвращает одно из следующего:

  1. Если проверка не пройдена, она возвращает объект, который содержит пару ключ-значение. Ключ — это имя ошибки, а значение всегда Booleantrue .
  2. Если проверка не завершится неудачей, возвращается ноль .

Теперь мы можем реализовать специальный валидатор ageRangeValidator в следующем листинге:

function ageRangeValidator(control: AbstractControl): { [key: string]: boolean } | null {

    if (control.value !== undefined && (isNaN(control.value) || control.value < 18 || control.value > 45)) {
        return { 'ageRange': true };
    }
    return null;
}

Здесь мы жестко прописываем максимальный и минимальный диапазон в валидаторе. В следующем разделе мы увидим, как передать эти параметры.

Теперь вы можете использовать ageRangeValidator с контролем возраста, как показано в коде ниже. Как видите, вам нужно добавить имя настраиваемой функции валидатора в массив:

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator])
    });
}

On the template, the custom validator can be used like any other validator. We are using the ageRange validation to show or hide the error message.

If the user does not enter an age between 18 to 45, then the reactive form will show an error:

Now the age control is working with the custom validator. The only problem with ageRangeValidator is that the hardcoded age range only validates numbers between 18 and 45. To avoid a fixed range, we need to pass the maximum and minimum age to ageRangeValidator.

Passing Parameters to a Custom Validator

An Angular custom validator does not directly take extra input parameters aside from the reference of the control. To pass extra parameters, you need to add a custom validator inside a factory function. The factory function will then return a custom validator.

You heard right: in JavaScript, a function can return another function.

Essentially, to pass parameters to a custom validator you need to follow these steps:

  1. Create a factory function and pass parameters that will be passed to the custom validator to this function.
  2. The return type of the factory function should be ValidatorFn which is part of @angular/forms
  3. Return the custom validator from the factory function.

The factory function syntax will be as follows:

Now you can refactor the ageRangeValidator to accept input parameters as shown in the listing below:

function ageRangeValidator(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
            return { 'ageRange': true };
        }
        return null;
    };
}

We are using the input parameters max and min to validate age control. Now, you can use ageRangeValidator with age control and pass the values for max and min as shown in the code below:

min = 10;
max = 20;
ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator(this.min, this.max)])
    });
}

On the template, the custom validator can be used like any other validator. We are using ageRange validation to show or hide an error message:

In this case, if the user does not enter an age between 10 and 20, the error message will be shown as seen below:

And there you have it: how to create a custom validator for Angular Reactive Forms.