меню

Реактивные формы — это одна из лучших вещей в Angular. Поскольку они упрощают работу с большими и действительно динамичными формами. В этой мы рассмотрим создание кастомного элемента формы.

Могут быть разные причины для создания собственных элементов управления формой.

  • можно сделать кастомный селект, который будет использоваться для выбора типа контакта и страны;
  • можно сделать собственный элемент для ввода пароля и его подтверждения, который будет содержать собственный валидатор и возвращать в форму всего одно значение;
  • или же, если бы у нас была необходимость в элементе 'agree terms & conditions' — мы бы могли создать для этой цели кастомный formControl, который использовали бы во многих компонентах приложения.

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

  • корректно отображать значение в UI;
  • корректно передавать введенное пользователем значение из UI в модель;
  • передавать состояние валидации в DOM, что бы к компоненту можно было применить необходимые стили;
  • в случае необходимости — иметь собственные валидаторы;
  • работать с модель-ориентированными формами;
  • работать с шаблон-ориентированными формами;

Создание собственного select'a

В этом примере мы рассмотрим создание достаточно простого компонента для выбора одного значения из списка возможных.

Angular cоздание собственного select

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

Итак, давайте начнем с создания компонента CustomSelectComponent, который принимает из родительского компонента массив options и отображает его в шаблоне. Также у нас есть метод OptionsSelect, который сохранят выбранное пользователем значение в свойство innerValue.

Этот компонент работает хорошо и мы уже можем использовать его в шаблоне формы, как только задекларируем его в модуле нашего приложения.

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

Иными словами — нам нужна возможность использовать form api директивы, например formControl:

Создание кастомного angular select

Хорошо, но как мы можем сделать из обычного компонента компонент типа formControl? Для этого нам нужно узнать что такое ControlValueAccessor, потому что это именно то, что использует Angular для построения коммуникаций между моделью формы и DOM элементом.

Реализация ControlValueAccessor в пользовательском элементе

Компонент может опционально реализовывать интерфейс ControlValueAccessor, который позволяет записывать значение в компонент и прослушивать его изменения. Этот интерфейс используется в директивах NgModel и FormControlName.

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

Интерфейс ControlValueAccessor выглядит следующим образом:

Интерфейс ControlValueAccessor

Итак, давайте перепишем наш компонент и реализуем в нем методы описанные выше:

Реализация ControlValueAccessor в пользовательском элементе

Здесь мы регистрируем обработчики событий, а также в методе writeValue:

  • проверяем что новое значение является необходимым для нас типом данных;
  • удостоверяемся что в нашем списке опций есть элемент с необходимым значением;
  • записываем новое значение в локальную модель selectedOption;
  • вызываем метод onChange, который информирует другие компоненты о том, что значение было изменено.

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

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

Регистрация ControlValueAccessor

Для регистрации аксессора используется мультипровайдер с токеном NG_VALUE_ACCESSOR. Его следует добавить в список провайдеров нашего компонента:

Использование мультипровайдера NG_VALUE_ACCESSOR

Здесь мы сообщаем этому токену о нашем компоненте. Также, следует обратить внимание на использование forwardRef. Это необходимо, поскольку класс нашего компонента еще не будет определен, когда провайдер будет зарегистрирован и нам нужно сообщить конструктору провайдера о том, что необходимо дождаться определения класса.

Использование кастомного элемента в реактивной форме

После того, как мы создали нашу модель формы, мы можем связать наш кастомный form Control с моделью с помощью директивы formControlName или formControl.

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

Использование кастомного элемента в реактивной форме

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

Использование кастомного элемента в реактивной форме в двухсторонней привязке данных

На этом все. Надеюсь этот материал был полезен для Вас.


Возможно, вам будет интересно

Subject

Использование класса Subject для создания сервиса, реализующего observable и observer в Angular

Angular Interceptor - перехватчик ошибок http

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

Шаблон и стили компонента

Стилилизация компонента в Angular, способы определения стилей, подключени внешнего файла стилей, вынесение кода шаблона во внешний файл html

Маршрутизация Angular подробное руководство

Маршрутизация Angular подробное руководство. Без маршрутизации (роутинга) вы никогда не сделаете качественное приложение.

Оформление заявки

Документы на создание сайта

Изучите наше коммерческое предложение, заполните БРИФ и отправьте его на почту maxidebox@list.ru. Изучив все пожелания из БРИФ-а, обратным ответом оповестим Вас по стоимости разработке, ответим на вопросы.

КП на создание сайта Коммерческое предложение на созданеи сайта

Мы берем на себя ответственность за все стадии работы и полностью избавляем клиентов от забот и необходимости вникать в тонкости.

Скачать БРИФ (акета) на создание сайта Скачать БРИФ (акета) на создание сайта

Зополните у БРИФ-а все необходимые поля. Сделайте краткое описание к каждому из пунктов анкеты, привидите примеры в соответсвующий пунктах - это позволит лучше понять Ваши ожидания и требования к сайту