Low-code дизайнер > Создание интерфейсов / Сценарии в виджетах

Сценарии в виджетах

Виджеты на странице можно сделать интерактивными с помощью сценариев.

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

Сценарии могут быть:

  • клиентскими — выполняются в браузере пользователя;
  • серверными — обрабатываются на сервере ELMA365;
  • смешанными — выполняются на стороне клиента и вызывают серверные методы.

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

В серверных сценариях можно использовать дополнительные параметры. Они позволяют донастроить виджет и внести изменения в сценарий без перепубликации. Подробнее об этом вы можете прочитать в статье «Дополнительные параметры».

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

Сценарии пишутся на языке TypeScript. Работа с ними осуществляется в дизайнере интерфейсов на вкладке Сценарии.

начало внимание

Использование констант Global или Namespace в сценариях ограничивает экспорт компонентов системы. Подробнее об этом читайте в статье «Глобальные константы в сценариях».

конец внимание

add-js

Внешние зависимости в клиентских сценариях

В клиентских сценариях виджета вы можете обращаться к библиотечным и пользовательским функциям на языке Javascript. Для этого перейдите в дизайнере на вкладку Файлы. Загрузите один или несколько файлов в формате .js с кодом функций или библиотек. На вкладке Сценарии в исходном коде скрипта подключите добавленные файлы с помощью инструкции import.

Например, чтобы подключить библиотеку jQuery, перейдите на вкладку Файлы и загрузите файл с актуальной версией библиотеки, например, jquery-3.6.0.min.js. Перейдите на вкладку Сценарии в раздел клиентских скриптов и в начале сценария добавьте инструкцию:

import $ from "jquery-3.6.0.min.js";

Теперь в коде сценария вы сможете обращаться к функциям библиотеки.

Также в клиентских сценариях виджетов поддерживаются функции, которые вызываются автоматически в процессе отображения виджета и при сохранении формы. Подробнее об этом читайте в статье «Системные функции виджетов».

Получение данных из виджетов

Способ получения данных из контекста в сценариях зависит от того, где настраивается виджет.

Виджеты интерфейсов

Если вы настраиваете интерфейс и создаёте пользовательский виджет, обращаться к его контексту следует с помощью константы Context, например:

Context.data.string_1 = 'string value';

К системным виджетам, расположенным на страницах, также необходимо обращаться через Context.

Виджеты на формах

Доступ к виджетам, расположенным на форме приложения, осуществляется с помощью константы ViewContext, так как константа Context в этом случае отвечает за контекст приложения:

const itemName = Context.data.__name;
ViewContext.data.string_1 = `Название ${ itemName }}`;

Вызов серверного метода из клиентского скрипта

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

Например, на сервере может быть сценарий, который выполняет обработку данных и может обращаться к внешним сервисам:

async function DoSomeWork() : Promise<void> {
  // Далее прописывается логика серверного сценария.
  // Вы можете использовать внешние вызовы через `await`
  let response = await fetch('https://my-service.mycompany.com/getmydata?token=' + Context.data.secureToken);
  Context.data.mySecureData = await response.text();
}

В коде на стороне клиента можно вызвать этот метод, используя свойство Server.rpc:

async function onButtonClick() : Promise<void> {
  ViewContext.data.blockUI = true;
  await Server.rpc.DoSomeWork();
  ViewContext.data.blockUI = false;
}

Обратите внимание, между сервером и клиентом данные передаются только через Context или ViewContext. Метод на стороне сервера должен быть без параметров и иметь возвращаемый тип Promise. Только тогда он появится в автодополнении в клиентском сценарии.

Вызывать серверные методы можно также с помощью вложенных виджетов, например, Кнопка или Код. Подробнее об этом читайте в справке ELMA365 TS SDK.

Отслеживание событий в приложениях через клиентский сценарий

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

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

начало внимание

Подписка на события элементов приложения доступна по умолчанию для поставки On-Premises, начиная с версии 2024.2. В более ранних версиях администратору системы нужно включить фича‑флаг enableSubscriptionOnEventsFromScript. Подробнее читайте в статьях «Изменение параметров On-Premises Enterprise» и «Изменение параметров On-Premises Standard». Для поставки SaaS обратитесь к вашему менеджеру ELMA365, чтобы включить фича-флаг.

конец внимание

Подписаться на событие

Для создания подписки на событие в приложении откройте вкладку Сценарии, перейдите в раздел клиентских скриптов и напишите сценарий:

await System.events.subscribe()
   
   // Подписка на событие создания нового элемента в приложении
   .onAppItemCreate(Context.fields.order.app, async (events) => {
       const event = events[0];
       const order = await event.data.fetch();
           
       // Обновление данных отчёта
       updateReportWithNew(order);
   },
   {
       debounce: 0
   })
   
   // Подписка на событие изменения определённого элемента, в том числе смену его статуса
   .onAppItemUpdate(item, function(e) => {}, { buffered: 2 })
   
   // Подписка на событие удаления определённого элемента
   .onAppItemDelete(item, function(e) => {}, { debounce: 0 })
   .all();

Основные параметры:

  • приложение или элемент, по которым отслеживаются события;
  • обработчик события — пользовательская функция, которая запускается при наступлении события.

Для оптимизации производительности можно также использовать необязательные параметры — опции обработчика:

  • buffered — укажите, сколько событий будет накапливаться, прежде чем они будут обрабатываться. По умолчанию 1;
  • debounce — задайте максимальную частоту вызова обработчика в миллисекундах. Обратите внимание, если за установленное время получено больше событий, чем указано в buffered, обрабатываются последние из них, а более ранние игнорируются. Для событий создания и удаления рекомендуется устанавливать значение 0, чтобы обрабатывались все элементы. Значение по умолчанию — 50 мс.

Отключить обработчик

Подписки на события активны, пока открыта страница с виджетом, для которого они настроены. При переходе на другую страницу они автоматически отключаются.

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

// Отключение обработчика `onDeleteHandler`, который использовался для события удаления элемента
await System.events.unsubscribe().onAppItemDelete(item, onDeleteHandler).all();
 
...
// Отключение всех обработчиков для события изменения элемента
await System.events.unsubscribe().onAppItemUpdate(item).all();
 
...
// Отмена всех подписок на события в рамках виджета
await System.events.unsubscribe().all();