Advertisement
  1. Code
  2. Angular

Введение в формы в Angular 4: Написание пользовательских валидаторов форм

Scroll to top
Read Time: 8 min
This post is part of a series called Introduction to Forms in Angular 4.
Introduction to Forms in Angular 4: Reactive Forms

Russian (Pусский) translation by Anna k.Ivanova (you can also view the original English article)

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

Предпосылки

Вам не нужно следовать части первой или второй этой серии, чтобы часть третья имела смысл. Однако, если вы совершенно не знакомы с формами в Angular, вам следует перейти к первому учебнику этой серии и начать с него.

В противном случае, возьмите копию этого кода с нашего репозитория GitHub и используйте его в качестве отправной точки.

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

Angular не имеет огромной встроенной библиотеки валидаторов. Начиная с Angular 4, у нас есть следующие популярные валидаторы в Angular:

  • required
  • minlength
  • maxlength
  • pattern

На самом деле есть еще несколько, и вы можете увидеть полный список в документации Angular.

Мы можем использовать вышеупомянутые встроенные валидаторы двумя способами:

1. Как директивы в шаблонно-управляемых формах.

2. В качестве валидаторов внутри конструктора FormControl в управляемых моделями формах.

Если приведенный выше синтаксис не понятен, то следуйте моим предыдущим учебникам по созданию формы регистрации с использованием подхода на основе шаблонов или подхода на основе моделей, а затем вернитесь назад!

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

Вот факт: формы на основе шаблонов - это формы на основе моделей. В форме, управляемой шаблоном, мы позволяем шаблону позаботиться о создании модели для нас. Очевидный вопрос сейчас заключается в том, как прикрепить валидатор к форме?

Валидаторы - это просто функции. В форме, управляемой моделью, присоединение валидаторов к FormControl является простым. Однако в форме, управляемой шаблоном, предстоит еще немного поработать. В дополнение к функции валидатора вам необходимо написать директиву для валидатора и создать экземпляры директивы в шаблоне.

Погружение в детали

Хотя это уже было рассмотрено, мы кратко рассмотрим код для формы регистрации. Во-первых, вот реактивный подход.

app/signup-form/signup-form.component.ts

FormBuilder - это синтаксический сахар, который создает экземпляры FormGroup и FormControl. FormControl отслеживает значение и статус проверки отдельного элемента формы. FormGroup, с другой стороны, содержит группу экземпляров FormControl и отслеживает значение и достоверность всей группы.

Вот структура, которой мы следовали:

В зависимости от требований мы можем присоединить валидатор к FormControl или FormGroup. Валидатор, занесенный в черный список электронной почты, должен был бы присоединить его к экземпляру FormControl электронной почты.

Однако для более сложных проверок, когда необходимо сравнивать и проверять несколько полей управления, лучше добавить логику проверки в родительскую группу FormGroup. Как видите, password имеет собственную группу FormGroup, и это облегчает нам написание валидаторов, которые проверяют равенство pwd и confirmPwd.

Для формы, управляемой шаблоном, вся эта логика входит в шаблон HTML, и вот пример:

app/signup-form/signup-form.component.html

ngModel создает экземпляр FormControl и связывает его с элементом управления формой. Точно так же ngModelGroup создает и связывает экземпляр FormGroup с элементом DOM. Они имеют ту же модель доменной структуры, которая обсуждалась выше

Также интересно отметить, что FormControl, FormGroup и FormArray расширяют класс AbstractControl. Это означает, что класс AbstractControl отвечает за отслеживание значений объектов формы, проверку их и включение других вещей, таких как pristine, dirty и touched методы.

Теперь, когда мы знакомы с обоими методами форм, давайте напишем наш первый пользовательский валидатор.

Пользовательская функция валидатора для управляемых моделями форм

Валидаторы - это функции, которые принимают экземпляр FormControl/FormGroup в качестве входных данных и возвращают либо null, либо объект ошибки. null возвращается, когда проверка прошла успешно, и если нет, то генерируется объект ошибки. Вот очень простая версия функции проверки.

app/password-match.ts

Я объявил функцию, которая принимает экземпляр FormGroup в качестве входных данных. Возвращает объект с ключом типа string и значением true/false. Это так, что мы можем вернуть объект ошибки в форме ниже:

Далее нам нужно получить значение экземпляров pwd и verifyPwd FormControl. Я собираюсь использовать control.get(), чтобы получить их значения.

Теперь нам нужно сделать сравнение, а затем вернуть либо ноль, либо объект ошибки.

app/password-match.ts

Почему я заменил FormGroup на AbstractControl? Как вы знаете, AbstractControl является матерью всех классов Form* и дает вам больше контроля над объектами управления формой. Это дает дополнительное преимущество, так как делает наш код проверки более согласованным.

Импортируйте функцию passwordMatch в компоненте RegistrationForm и объявите ее как валидатор для экземпляра FormGroup пароля.

app/password-match.ts

Отображение ошибок

Если вы все сделали правильно, password.errors?.mismatch будет иметь значение true, если значения обоих полей не совпадают.

Хотя существуют альтернативные способы отображения ошибок, я собираюсь использовать директиву ngIf, чтобы определить, должно ли отображаться сообщение об ошибке или нет.

Во-первых, я собираюсь использовать ngIf, чтобы узнать, является ли пароль недействительным.

Мы используем password.touched, чтобы гарантировать, что пользователь не встретится с ошибками ещё до нажатия клавиши.

Далее я собираюсь использовать выражение ngIf ="expression; then a else b" для отображения правильной ошибки.

app/signup-form/signup-form.component.html

Вот вам и рабочая модель валидатора, который проверяет равенство паролей.

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

Пользовательская директива валидатора для управляемых шаблонами форм

Мы будем использовать ту же функцию валидатора, которую мы создали для формы, управляемой моделью ранее. Однако у нас нет прямого доступа к экземплярам FormControl/FormGroup в форме, управляемой шаблоном. Вот что вам нужно сделать, чтобы валидатор работал:

  1. Создайте PasswordMatchDirective, который служит оболочкой для функции валидатора passwordMatch. Мы будем регистрировать директиву как валидатор, используя провайдера NG_VALIDATORS. Подробнее об этом позже.
  2. Прикрепите директиву к шаблону формы управления.

Давайте сначала напишем директиву. Вот как выглядит директива в Angular:

app/password-match.ts

Декоратор @Directive используется для обозначения класса как Angular директивы. Он принимает объект в качестве аргумента, который задает метаданные конфигурации директивы, такие как селекторы, к которым должна быть присоединена директива, и список провайдеров, которые должны быть внедрены, и т.д. Давайте заполним метаданные директивы:

app/password-match.ts

  1. Директива теперь присоединена ко всем элементам управления вводом, которые имеют атрибуты ngModelGroup и passwordMatch.
  2. Мы расширяем встроенные валидаторы, используя провайдера NG_VALIDATORS. Как упоминалось ранее, NG_VALIDATORS - это поставщик, который имеет расширяемую коллекцию валидаторов. Функция passwordMatch, которую мы создали ранее, объявляется как зависимость. Multi: true устанавливает этого провайдера как мульти-провайдера. Это означает, что мы будем добавлять к существующей коллекции валидаторов, предоставленных NG_VALIDATORS.

Теперь добавьте директиву в массив объявлений в ngModule.

app/app.module.ts

Отображение сообщений об ошибках

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

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

Заключение

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

Валидаторы - это функции, которые возвращают null или объект ошибки. В управляемых моделями формах мы должны присоединить валидатор к экземпляру FormControl/FormGroup, и все. Процедура была немного более сложной в управляемой шаблоном форме, потому что нам нужно было создать директиву поверх функции валидатора.

Если вы хотите продолжить изучать JavaScript, не забудьте проверить, что у нас есть на Envato Market.

Я надеюсь, что вам понравилась эта серия Формы в Angular. Я хотел бы услышать ваши мысли. Поделитесь ими в комментариях.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.