Библиотека форм для инфраструктуры веб-компонентов Lightning (LWC)

Если вы разработчик Salesforce, скорее всего, вы создали множество форм. Предприятиям нравятся формы, обычно большие, с большим количеством входных данных и логическим условным рендерингом этих входных данных. Formlette - произносится как омлет - это библиотека для создания таких форм во фреймворке Lightning Web Components (LWC) Salesforce.

Требования к предприятиям обычно звучат примерно так: Соберите от пользователей целую кучу данных, но не забрасывайте их сразу всеми полями ввода; вместо этого отображайте только те поля, которые являются релевантными на основе данных, которые они уже заполнили oud . Я создал formlette, чтобы упростить процесс построения таких форм в LWC, разместив состояние форм в одном месте и отделив логику условного рендеринга от разметки, настроив каждый элемент в форме для рендеринга на основе данных. размещается в форме.

Что делает Formlette?

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

с таким кодом:

Как им пользоваться?

Formlette предоставляет разработчику два компонента LWC:

  1. формаАннотация
  2. форма

formAbstract

Абстрактный компонент, который должен быть расширен компонентом, реализующим форму. Компонент formAbstract предоставляет субкомпоненту (расширяющему его) общее состояние для размещения данных формы и функций для обновления, проверки и доступа к указанным данным. Компонент formAbstract предоставляет следующие общедоступные свойства:

values Часть состояния формы, в которой хранятся значения всех дочерних компонентов ввода в форме, привязанные к имени компонента ввода.

touched Состояние, в котором хранится информация о том, какие дочерние компоненты в форме были затронуты пользователем (даже если они не были заполнены - часто полезно для аналитики), с ключом по имени компонента ввода. .

visibilities Состояние, в котором хранится информация о том, какие из формлетов (компонент formlette и его api описаны в следующем подразделе) в форме видны в любое время с помощью клавиш по имени formlette.

getVisibleData() Метод, возвращающий значения всех видимых полей формы.

handleValueChange(): метод обработчика событий, который позволяет дочернему компоненту устанавливать значения в форме для событий DOM. Полезно для установки значений из компонентов, которые не имеют логики условного рендеринга и, следовательно, не нуждаются в оболочке с помощью компонента formlette.

handleTouched() Метод обработчика событий, который позволяет дочернему компоненту устанавливать состояние касания в форме для событий DOM. Это вызывается компонентом formlette в focusout.

updateValuesAndVisibilities Метод, который принимает в качестве параметра объект JS входных значений, привязанных к их именам, обновляет состояние values ​​ и обновляет, какие компоненты должны быть видимыми, на основе этих обновленных значений. Это предназначено для использования для заполнения одного или нескольких полей в форме на основе внешних входных данных (а не пользовательских).

validateInputs() Выполняет проверки для всех видимых входных данных и возвращает истину для всех видимых полей в форме, в которых есть допустимые входные данные. Для использования этого метода проверки компонент должен быть оформлен классом formlette-input. Этот метод предполагает, что компонент ввода внутри формы является базовым компонентом молниеносного ввода Salesfroce. Если вам нужно такое же поведение проверки для вашего настраиваемого компонента ввода, ему просто нужно реализовать методы reportVailidity () и checkValidity (), которые должны работать аналогично компонентам ввода молнии, как указано в следующей ссылке.



форма

Компонент, который обтекает входные компоненты в форме и предоставляет им логику условного рендеринга. Он предоставляет следующие общедоступные свойства.

name Имя компонента, которое будет использоваться в качестве ключа в состоянии формы

visibilityState Принимает часть состояния от родительского компонента, в которой находятся логические значения, определяющие, должна ли формалет быть видимой. Это свойство необходимо для определения того, какие формы должны быть видны. Он передается только явно, поскольку LWC не имеет аналога контексту React для поддержки неявной передачи реквизитов (тот факт, что visibilityState необходимо передавать явно, на мой взгляд, довольно уродлив, но на данный момент альтернативы в LWC нет. ; воспринимайте это как необходимый синтаксис для использования библиотеки формлетов).

trackTouch Boolean, чтобы указать, должно ли состояние формы отслеживать, касался ли пользователь ввода, заключенного в formlette. Если установлено значение true, компонент запускает обновление для события html «focusout», чтобы сообщить состоянию формы, что эта форма-буква была «затронута». По умолчанию это логическое значение false.

config Принимает необязательный объект конфигурации, который описывает логику того, когда визуализировать конкретную форму-буклет. В настоящее время конфигурация представляет собой объект JS, который поддерживает следующие свойства:

  1. parentName - имя родительского бланка, значение которого определяет, будет ли эта бланкета отображаться.
  2. showFor - значение или список значений, которые родитель может иметь, чтобы эта форма была видимой
  3. showIfExists - логическое значение, которое, если установлено в true, гарантирует, что формуляр будет виден, если родительский элемент заполнен

Как правило, вам нужно заполнить поле «showFor» или «showIfExists». Если оба заполнены, поведение, определенное параметром «showFor», будет иметь приоритет.

Рекомендации по использованию

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

Для повышения производительности заключите в форму (родительскую или дочернюю) только те входы, которые отвечают за условное поведение отрисовки, с помощью компонента formlette. Остальные входные данные могут по-прежнему хранить данные в состоянии формы, будь то значения или затронутый статус с помощью handleValueChange () и handleTouched (), соответственно, в компоненте formAbstract. Имя ключа, по которому должно сохраняться состояние, определяется атрибутом html name. Это демонстрируется в html-файле в примере кода, где первый ввод - это просто молниеносный ввод, который не заключен в формуляр.

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

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

Отношение отрисовки между формлетами представлено в виде графика зависимости, который создается на основе значений в свойствах config формлетов в форме. Давайте посмотрим на пример с тремя уровнями условной логики рендеринга, где входные значения «прародительских» компонентов определяют, должны ли рендериться «родительские» компоненты, а значения которых определяют, должны ли рендериться «дочерние» компоненты.

График зависимости, сгенерированный из объектов конфигурации, может выглядеть так.

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

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

Когда значение компонента изменяется, нам нужно только пройти вниз по поддереву этого компонента, чтобы определить, какие из его дочерних элементов претерпели изменения в видимости. Нам не нужно вычислять видимость всех формлетов формы. Таким образом, представляя бланки в виде графика, мы выполняем «поиск в ширину», начиная с бланка, значение которого изменилось, и перемещаемся вниз по дереву (графику) для вычисления состояние видимости каждого из его дочерних элементов (и внуков).

Мы выполняем поиск в ширину (в отличие от поиска в глубину), потому что мы хотим вычислить видимость в порядке дедушки и бабушки в первую очередь, родители во вторую и дети в последнюю очередь. Это связано с тем, что состояние формы сохраняется даже тогда, когда конкретная formlette и ее дочерние элементы скрыты, поэтому, когда formlette, который был ранее скрыт, снова становится видимым, его сохраненное значение может быть используется для определения видимости своих дочерних элементов. Другими словами, поиск в ширину аналогичен обходу дерева, когда мы сначала проходим каждый уровень, прежде чем перейти на следующий уровень.