Использование многоуровневых подвиджетов

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

  • Использование множества уровней вложенных подвиджетов
  • Изменение ссылок шаблонов подвиджетов в режиме выполнения
  • Передача параметров подвиджетам

Исходные данные

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

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

Аппарат предоставляет таблицу Содержимое (contents) со следующими полями:

  • Слот - описание диспенсора
  • Тип - тип диспенсора (маленький, средний или большой)
  • Продукт - имя продукта, загруженного в данный момент в диспенсор
  • Количество - количество легкой закуски, которая в данный момент находится в диспенсоре
  • Емкость - текущая емкость диспенсора

Вот как выглядит таблица Содержимое:

Таким образом, в машине шесть слотов с диспенсорами различных типов, установленных в них. Предположительно каждый слот может иметь диспенсор любого типа (маленький, средний или большой). В нашем случае слоты Slot1 и Slot2 имеют Маленькие диспенсоры, Slot3 и Slot4 - Средние диспенсоры, а Slot5 и Slot6 заняты Большими диспенсорами. Это динамическая компоновка, сконфигурированная инженерами во время установки аппарата.

Ниже представлен скриншот формата таблицы содержимого аппарата:

Структура виджетов компоновки аппарата

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

Модель нашей демо-машины определяет три типа диспенсоров: Маленький (код: 1), Средний (код: 2) и Большой (код: 3). Таким образом, необходимо разработать три виджета Компоновка диспенсора для использования их в качестве подвиджетов в Компоновке машины.

Разработка компоновок диспенсора

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

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

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

Наш упрощенный шаблон диспенсора будет содержать четыре компонента метка:

  • Метка имени продукта
  • Метка количества
  • Метка емкости
  • Метка сепаратора для демонстрации использования емкости как "количество / емкость"

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

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

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

Разработка компоновки машины

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

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

Наш простой виджет компоновки машины состоит из двух вертикально расположенных частей:

  • Метка заголовка, показывающая описание машины
  • Панель, содержащая шесть подвиджетов диспенсоров

Вот как он выглядит в рабочей форме Редактора виджетов (с активированными декорациями):

Динамическое определение шаблонов подвиджетов

Тип диспенсора, в данный момент установленного в слоте, определяется полем Тип диспенсора (type) в таблице Содержимое. Таким образом, нам потребуется шесть привязок, которые меняют свойство Ссылки компонентов подвиджета во время запуска главного виджета. Вот как должна выглядеть привязка шаблона подвиджета:

Цель

form/slot1:reference

Выражение

'users.admin.widgets.dispenser_' + select({.:contents}, "type", "slot", "Slot1")

Активатор


Условие


Опции

On Startup

Эта привязка меняет ссылку шаблона подвиджета, представляющего содержимое Slot1. Она рассчитывается при запуске главного виджета. Его выражение выстраивает путь контекста подвиджета, который нужно использовать для орисовки содержимого текущего слота. Это делается путем связывания префикса пути контекста (users.admin.widgets.dispenser_) и значения типа диспенсора, установленного в слоте (возвращенного путем выбора значения поля type из строки таблицы contents, чье поле slot равно Slot1).

Декларирование параметров подвиджетов диспенсора

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

  • Путь контекста устройства машины, направляющий подвиджет диспенсора на определенную машину (в нашем уроке контекст устройства будет заменен контекстом модели)
  • Идентификатор строки слота, чье содержимое представлено экземпляром подвиджета диспенсора

См. статью подвиджеты для получения более подробной информации о параметрах подвиджета.

Для определения парметра подвиджета диспенсора:

Свойства для добавления:

  • Свойство по имени device с одним полем Строка, также имеющим имя device (оставьте все остальные настройки по умолчанию)
  • Свойство по имени slot с одним полем Строка, также имеющим имя slot (оставьте все остальные настройки по умолчанию)

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

Виджет компоновки машины создаст отдельный экземпляр подвиджета диспенсора для каждого диспенсора в машине. Каждый подвиджет получит значения свойств device и slot из виджета верхнего уровня. Теперь нужно использовать эти значения в наших подвиджетах диспенсора. В нашем случае все три подвиджета диспенсора похожи, но в реальной жизни могут значительно отличаться друг от друга.

Привязки подвиджетов диспенсора, возможно, самые сложные во всей структуре. Вот пример привязки, которая показывает имя загруженного продукта в метке product:

Цель

form/product:text

Выражение

select(getVariable({form/:device$device}, "contents"), "product", "slot", {form/:slot$slot})

Активатор


Условие


Опции

On Startup

Привязка активируется один раз при запуске подвиджета. Она загружает переменную contents из контекста машины, указанной параметром device (на которого идет ссылка из {form/:device$device}). Как только загружается все содержимое таблицы, выражение привязки выбирает значение колонки product из записи, где колонка slot равна значению параметров подвиджета slot (доступных через ссылку {form/:slot$slot}).

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

Вот как выглядит финальная таблица привязок подвиджетов диспенсора:

Тестирование подвиджетов диспенсора

Несмотря на относительную простоту подвиджетов диспенсора, потребуется некоторое время для их тестирования и отладки. Отладка подвиджетов, запущенных в виджете компоновки машины, может доставить ненужные затруднения, но, к счастью, возможно протестировать его отдельно, вручную вводя значения параметров device и slot:

  • Откройте шаблон диспенсора в Редакторе виджетов
  • Выберите Корневая панель в Дереве ресурсов
  • Щелкните правой кнопкой по любой ячейке Сетки свойств
  • Перейдите во вкладку Пользовательские свойства
  • Задайте параметр device в виде users.admin.models.vending_machine (это серверый путь контекста нашего контекста модели машины; путь должен указывать на тестовую вендинговую машину)
  • Задайте параметр slot на Slot1 для тестирования подвиджета диспенсора в содержимом Slot1
  • Запустите подвиджет путем нажатия на иконку панели управления ()

Виджет отобразит содержимое Slot1 тестовой машины:

Создание подвиджетов других диспенсоров

После завершения и тестирования шаблона подвиджета Маленького диспенсора создайте две его копии, используя действие Создать копию (), задайте для этих копий надлежащие имена/описания (убедитесь, чтобы имена соответствовали образцу dispenser_X !) и внесите необходимые изменения, чтобы другие диспенсоры отличались друг от друга.

Связывание слотов в компоновке машины

Теперь мы подошли к финальному этапу урока. Последней задачей станет обеспечение корректных значений времени выполнения параметров device и slot для каждого подвиджета диспенсора в пределах виджета Компоновка машины. Параметр device назначается группой из шести подобных привязок:

Цель

form/slot1:device

Выражение

dc()

Активатор


Условия


Опции

On Startup

Эта привязка определяет пользовательское свойство device компонента подвиджета slot1 на путь контекста по умолчанию виджета Компоновка машины (возвращенного функцией dc()).

Вот как выглядит финальная таблица Всех привязок виджета Компоновка машины:

Правильное определение свойства slot может быть непростым. Каждый подвиджет диспенсора в слоте должен получать собственное значение статических параметров (Slot1, Slot2 и т.д.). Однако если мы выбираем компоненты подвиджета в Рабочей форме, мы не видим вкладку Пользовательские свойства в окне Свойства, потому что у них не определен статический шаблон. Чтобы задать параметр slot, надо вручную задать каждому подвиджету параметр Reference к пути любого из наших подвиджетов диспенсора. После этого нужно задать параметр slot наших подвиджетов как Slot1, Slot2 и т.д.

В таблице Все привязки нашей Компоновки машины привязки, меняющие шаблоны подвиджетов диспенсора (свойства Ссылка), должны предшествовать привязке, которая задает внутренние параметры этого подвиджета (device и slot). В этом случае значения параметров будут получены "правильными" подвиджетами диспенсора.

Тестирование визуализации компоновки машины

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

Вот как выглядит результат:

Что дальше

Описанная система отрисовки вендингового аппарата может быть расширена при помощи:

  • Разработки виджетов для различных компоновок машин и типов диспенсоров
  • Отрисовки машин более сложной структуры (например, машины с несколькими отделениями, содержащими заменяемые мультидиспенсорные держатели)
  • Диспенсоры с цветовым кодированием в зависимости от количества оставшихся запасов
  • Разработка профессионально отрисованных компоновок виджетов