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

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

Сегодня мы поговорим о типах компонентов, которые мы хотим использовать в формах Angular или с ngModel, мы говорим об элементах, которые хранят значение, например: входы, селекторы, средства выбора даты. В общем, любой элемент, который хранит значение и отправляет новый результат при взаимодействии с пользователем.

Чтобы понять, как использовать директиву ngModel или formControl в наших веб-компонентах, важно понимать, как angular управляет использованием <input/> или <textarea></textarea>

Если мы посмотрим на https://www.w3schools.com/tags/tag_input.asp, то увидим, что у этих элементов есть общие свойства, а именно:

  • value: как свойство, хранящее ценность
  • onChange: как выходное событие, уведомляющее об изменении этого значения

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

Как работает Angular?

Директивы Angular, такие как ngModel, formControl и formControlName, используют режим по умолчанию в Angular для определения логики доступа к элементам.

Если мы посмотрим на angular/core code, мы увидим реализацию директивы DefaulValueAccesor.

Https://github.com/angular/angular/blob/9.1.x/packages/forms/src/directives/default_value_accessor.ts#L47

В этом файле мы можем найти две разные части:

Селектор:

Здесь мы видим, что эта директива влияет на ведьмовские элементы.

Реализация:

Здесь мы можем увидеть, как value property и событие onChange управляется Angular.

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

Как включить ngModel и formControl в наших веб-компонентах?

Есть два способа разрешить использование ngModel и formControl с нашими веб-компонентами.

Первый, если мы реализовали наш веб-компонент стандартным способом, который мы определили в предыдущих абзацах, будет просто сообщать Angular, что наш компонент будет использовать DefaultValueAccesor, поэтому Angular пытается найти value и onChange внутри нашего компонента.

Если мы вспомним первый фрагмент кода, в котором мы объясняли, как работает Angular, последним элементом селектора был: [ngDefaultControl], это означает, что если какой-либо компонент, в котором вы используете ngModel, и имеет этот атрибут, Angular будет использовать поведение по умолчанию.

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

Использование ngModel и formControl как профессионал

Как мы уже упоминали ранее, мы можем заставить наши компоненты использовать ngModel или formControl, не сообщая Angular использовать режим по умолчанию или не реализуя стандартное значение value onChange system.

Для этого мы собираемся переопределить DefaultValueAccesor, чтобы указать элементу angular witch, который мы хотим использовать с ngModel, и какие входы и выходы элемента должны использовать angular.

Как мы можем видеть в этом фрагменте кода, сначала мы собираемся определить, какие HTML-теги должны быть затронуты этой директивой, а затем сообщить Angular с помощью свойства или события, которое должно наблюдаться внутри нашего компонента, чтобы выполнить успешную привязку данных или использовать formControl. характеристики вроде onFocus или onDirty.

Итак, с этого момента нам нужно только добавить этот файл в наше объявление массива в модулях, на которые мы хотим повлиять, и использовать [(ngModel)] или formControl с нашими веб-компонентами. Как я уже упоминал, ReactiveForm также использует этот селектор, поэтому все их возможности можно использовать с веб-компонентами.

Некоторые рекомендации

Даже если вы можете создать свой веб-компонент, используя желаемое имя для свойств значения и выходных событий, я настоятельно рекомендую попытаться сохранить стандартное соглашение об именах, что означает использование значения в качестве свойства, onChange, onBlur или onFocus для изменения, размытия и фокус событий. При этом вам сначала понадобится только одно переопределение ControlValue со всем объявлением вашего селектора.