Модуль в Creatio является изолированной программной единицей. Ему ничего не известно об остальных модулях системы, кроме имен модулей, от которых он зависит. Для организации взаимодействия модулей предназначен специальный объект — sandbox.
Sandbox предоставляет два ключевых механизма взаимодействия модулей в системе:
- Механизм обмена сообщениями между модулями.
- Загрузка и выгрузка модулей по требованию (для визуальных модулей).
Обмен сообщениями между модулями
Модули могут общаться друг с другом только посредством сообщений. Модуль, которому требуется сообщить об изменении своего состояния другим модулям в системе, публикует сообщение. Если модулю необходимо получать сообщения об изменении состояний других модулей, он должен быть подписанным на эти сообщения.
Зарегистрировать сообщение
Чтобы модули могли обмениваться сообщениями, сообщения необходимо зарегистрировать.
Для регистрации сообщений модуля предназначен метод sandbox.registerMessages(messageConfig), где messageConfig — конфигурационный объект сообщений модуля.
Конфигурационный объект является коллекцией "ключ-значение", в которой каждый элемент имеет вид, представленный ниже.
Здесь MessageName — ключ элемента коллекции, содержащий имя сообщения. Значением является конфигурационный объект, содержащий два свойства:
- mode — режим работы сообщения. Должно содержать значение перечисления Terrasoft.MessageMode (Terrasoft.core.enums.MessageMode).
- direction — направление сообщения. Должно содержать значение перечисления Terrasoft.MessageDirectionType (Terrasoft.core.enums.MessageDirectionType).
Режимы обмена сообщениями (свойство mode):
- Широковещательный — режим работы сообщения, при котором количество подписчиков заранее неизвестно. Соответствует значению перечисления Terrasoft.MessageMode.BROADCAST.
- Адресный — режим работы сообщения, при котором сообщение может быть обработано только одним подписчиком. Соответствует значению перечисления Terrasoft.MessageMode.PTP.
Направления сообщения (свойство direction):
- Публикация — модуль может только опубликовать сообщение в sandbox. Соответствует значению перечисления Terrasoft.MessageDirectionType.PUBLISH.
- Подписка — модуль может только подписаться на сообщение, опубликованное из другого модуля. Соответствует значению перечисления Terrasoft.MessageDirectionType.SUBSCRIBE.
- Двунаправленное — позволяет публиковать и подписываться на одно и то же сообщение в разных экземплярах одного и того же класса или в рамках одной и той же иерархии наследования схем. Соответствует значению перечисления Terrasoft.MessageDirectionType.BIDIRECTIONAL.
В схемах модели представления регистрировать сообщения с помощью метода sandbox.registerMessages() не нужно. Достаточно объявить конфигурационный объект сообщений в свойстве messages.
Для отказа от регистрации сообщений в модуле можно воспользоваться методом sandbox.unRegisterMessages(messages), где messages — имя или массив имен сообщений.
Добавить сообщение в схему модуля
Зарегистрировать сообщения можно также, добавив их в схему модуля с помощью дизайнера.
Для добавления сообщения в схему модуля:
-
В области свойств модуля дизайнера схемы модуля добавьте сообщение в узел Сообщения(Messages).
-
Для добавленного сообщения установите необходимые свойства:
- Название (Name) — имя сообщения, совпадающее с ключом в конфигурационном объекте модуля.
- Направление (Direction) — направление сообщения. Возможные значения "Подписка" ("Follow") и "Публикация" ("Publish").
- Режим (Mode) — режим работы сообщения. Возможные значения "Широковещательное" ("Broadcast") и "Адрес" ("Address").
Опубликовать сообщение
Для публикации сообщения предназначен метод sandbox.publish(messageName , messageArgs, tags).
Для сообщения, опубликованного с массивом тегов, будут вызваны только те обработчики, для которых совпадает хотя бы один тег. Сообщения, опубликованные без тегов, смогут обработать только подписчики без тегов.
Подписаться на сообщение
Подписаться на сообщение можно, используя метод sandbox.subscribe(messageName, messageHandler, scope, tags).
Загрузка и выгрузка модулей
При работе с пользовательским интерфейсом Creatio может возникнуть необходимость загрузки не объявленных как зависимости модулей во время выполнения приложения.
Загрузить модуль
Для загрузки не объявленных в качестве зависимостей модулей предназначен метод sandbox.loadModule(moduleName, config). Параметры метода:
- moduleName — название модуля.
- config — конфигурационный объект, содержащий параметры модуля. Обязательный параметр для визуальных модулей.
Выгрузить модуль
Для выгрузки модуля необходимо использовать метод sandbox.unloadModule(id, renderTo, keepAlive). Параметры метода:
- id — идентификатор модуля.
- renderTo — название контейнера, из которого необходимо удалить представление визуального модуля. Обязателен для визуальных модулей.
- keepAlive — признак сохранения модели модуля. При выгрузке модуля ядро может сохранить его модель для возможности использовать ее свойства, методы, сообщения. Не рекомендуется к использованию.
Создать цепочку модулей
Иногда возникает необходимость показать представление некой модели на месте представления другой модели. Например, для установки значения определенного поля на текущей странице нужно отобразить страницу выбора значения из справочника SelectData. В таких случаях нужно, чтобы модуль текущей страницы не выгружался, а на месте его контейнера отображалось представление модуля страницы выбора из справочника. Для этого можно использовать цепочки модулей.
Чтобы начать построение цепочки, достаточно добавить свойство keepAlive в конфигурационный объект загружаемого модуля.
1. Создать модуль
- Перейдите в раздел Конфигурация (Configuration) и выберите пользовательский пакет, в который будет добавлена схема.
-
На панели инструментов реестра раздела нажмите Добавить —> Модуль (Add —> Module).
-
В дизайнере модуля заполните свойства схемы:
- Код (Code) — "UsrSomeModule".
- Заголовок (Title) — "SomeModule".
Для применения заданных свойств нажмите Применить (Apply).
-
В дизайнере модуля добавьте исходный код.
- На панели инструментов дизайнера модуля нажмите Сохранить (Save).
2. Зарегистрировать сообщения
- Объявите конфигурационные объекты сообщений в свойстве messages схемы.
- В метод init() добавьте вызов метода sandbox.registerMessages(), который регистрирует сообщения.
3. Опубликовать сообщение
- В схеме модуля реализуйте метод processMessages().
- В методе processMessages() вызовите метод sandbox.publish(), который публикует сообщение MessageToPublish.
- В метод init() добавьте вызов метода processMessages().
4. Подписаться на сообщение
- В метод processMessages() добавьте вызов метода sandbox.subscribe(), который подписывается на сообщение MessageToSubscribe, которое отправляет другой модуль.
- В параметрах метода укажите метод-обработчик onMessageSubscribe() и добавьте его в исходный код модуля.
5. Отменить регистрацию сообщений
- В модуле, который публикует сообщение, укажите конфигурационный объект в качестве параметра функции-обработчика.
-
В конфигурационный объект добавьте функцию обратного вызова (callback-функцию).
-
В методе-обработчике модуля-подписчика при подписке на сообщение верните асинхронный результат. Используйте параметр callback-функции опубликованного сообщения.
В схеме BaseEntityPage пакета CrtNUI зарегистрировано сообщение CardModuleResponse. Схема BaseEntityPage — базовая схема модели представления страницы записи.
Например, Creatio публикует сообщение после сохранения измененной записи. Эта функциональность реализована в дочерней схеме BasePageV2 пакета CrtNUI.
Миксин LookupQuickAddMixin указан в схеме BasePageV2 в качестве зависимости. В миксине реализована подписка на сообщение CardModuleResponse. Читайте подробнее в статье Клиентская схема.
Последовательность работы с двунаправленным сообщением при добавлении нового адреса на странице контакта:
-
Модуль ContactAddressPageV2 загружается в цепочку модулей на деталь Адреса (Addresses).
-
Oткрывается страница адреса контакта.
Поскольку схема ContactAddressPageV2 наследует схемы BaseEntityPage и BasePageV2, то в ней уже зарегистрировано сообщение CardModuleResponse. Это сообщение также регистрируется в методе _registerMessages() миксина LookupQuickAddMixin при его инициализации в качестве модуля-зависимости BasePageV2.
- При добавлении нового значения в справочные поля страницы ContactAddressPageV2 (например, нового города) вызывается метод onLookupChange() миксина LookupQuickAddMixin.
- Модуль CityPageV2 загружается в цепочку модулей.
- В методе onLookupChange() вызывается метод _subscribeNewEntityCardModuleResponse(), в котором осуществляется подписка на сообщение CardModuleResponse.
-
Открывается страница города (схема CityPageV2 пакета CrtUIv2).
- Поскольку схема CityPageV2 наследует схему BasePageV2, то после сохранения записи (кнопка Сохранить (Save)) выполняется метод onSaved() базовой схемы.
- Метод onSaved() вызывает метод sendSaveCardModuleResponse(), который публикует сообщение CardModuleResponse. При этом передается объект с необходимыми результатами сохранения.
-
После публикации сообщения выполняется callback-функция подписчика (метод _subscribeNewEntityCardModuleResponse() миксина LookupQuickAddMixin), в которой обрабатываются результаты сохранения нового города в справочник.
Таким образом, публикация и подписка на двунаправленное сообщение выполнены в рамках одной иерархии наследования схем. В этой иерархии базовая схема BasePageV2 содержит всю необходимую функциональность.
1. Создать класс визуального модуля
Создайте класс модуля UsrCardModule, который наследует базовый класс BaseSchemaModule. Класс должен быть инстанцируемым, то есть возвращать функцию-конструктор. В этом случае, при загрузке модуля извне вы можете передать в конструктор необходимые параметры.
2. Создать класс модуля, в который загружается визуальный модуль
Создайте класс модуля UsrModule, который наследует класс BaseModel.
3. Загрузить модуль
Вы можете передавать параметры в конструктор класса инстанцируемого модуля при загрузке модуля. Для этого:
- В классе модуля UsrModule создайте конфигурационный объект.
- В качестве свойств конфигурационного объекта укажите требуемые значения.
- Загрузите визуальный модуль UsrCardModule с помощью метода sandbox.loadModule().
- В метод sandbox.loadModule() добавьте свойство instanceConfig.
- В качестве значения свойства instanceConfig передайте конфигурационный объект, который содержит требуемые значения.
Чтобы передать дополнительные параметры при загрузке модуля, используйте свойство parameters конфигурационного объекта. Предварительно реализуйте такое же свойство в классе модуля или в одном из родительских классов. Свойство parameters определено в базовом классе BaseModule. При создании экземпляра модуля свойство parameters модуля будет проинициализировано значениями, которые переданы в свойстве parameters конфигурационного объекта.