Привязки сервера

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

Фронтэнд привязки дополняют синтаксис серверных привязок путем добавления возможности ссылаться на UI компоненты инструментальных панелей.

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

Основные параметры серверных привязок:

  • Активатор, Условие привязки и флаги, определяющие, КОГДА обрабатывается привязка. Обработка может происходить при запуске сервера или инструментальной панели, нажатии кнопки, изменениях в переменных или свойствах инструментальных панелей, возникновении нового события и т.д.

  • Выражение привязки рассчитывается каждый раз при активации привязки. Значение вычисления определяет КАКОВ результат обработки привязок. Выражение привязки может ссылаться на различные значения из свойств компонента "инструментальная панель" или различные данные из контекстов сервера. Результат вычисления отправляется в цель привязки.

  • Цель привязки - это ссылка, определяющая, ГДЕ будет записываться результат расчета выражения привязки, т.е., какое свойство компонента графического интерфейса пользователя или какие данные контекста будут меняться.

Активация привязок

Активация привязок сервера контролируется:

  • Параметр При запуске - когда он активирован, привязка обрабатывается каждый раз когда запускается набор привязок. В случае с привязками модели это запуск AggreGate Server или изменение конфигурации модели. Для привязок инструментальной панели это момент, когда пользователь открывает инструментальную панель в браузере.

  • Параметр По событию - когда параметр включен и задан Активатор, привязка выполняется при изменении свойства, на которое ссылается активатор. Если Активатор ссылается на событие, привязка будет выполнена при генерации события. Если Активатор ссылается на переменную, то привязка выполнится когда изменится значение переменной. Если Активатор не определен и Выражение привязки включает ссылки на одну и более переменные, то изменение любой переменной вызовет выполнение привязки.

  • Активатор - это ссылка на какое-то событие или свойство контекста, которое вызывает выполнение привязки. Параметр Активатор доступен только когда установлен флаг По событию.

  • Параметр Периодически - если данный параметр включен, то привязка будет выполняться с регулярными интервалами, определенными в настройке Период.

  • Условие это Выражение AggreGate, которое вычисляется первым после активации привязки. Если результат вычисления выражения false, выполнение привязки сбрасывается.

  • Очередь - это имя очереди обработки цели привязки. Движок привязок гарантирует, что цели привязок, которые принадлежат одной очереди, будут доступны в том же порядке, в котором были выполнены привязки. Параметр Очередь в некоторых окружениях выполнения привязок, например, в привязках модели.

Порядок активации привязок

Поскольку привязки выполняются параллельно, порядок их выполнения нефиксированнный. Если две привязки активируются одновременно, нельзя определить, какая из них будет выполнена первой. Это важно учитывать при создании привязок, зависящих от результатов других привязок.

Например, одна привязка обновляет свойство контекста, а другая привязка активируется этим событием. Она запускает функцию, если указанное свойство контекста было обновлено. Обе привязки активируются одновременно. Если привязка, обновляющая свойство, выполнится первой, вторая привязка вызовет функцию. Если же первой будет выполнена привязка, вызывающая функцию, функция не будет вызвана. В результате, событие, которое должно было запустить выполнение этой привязки, будет проигнорировано.

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

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

Such a reactivated binding may cause loss of user input in its Target if designed improperly. If this is not acceptable, a binding should take into account previously changed data in its Target (by referring its own Target from its Expression). The Expesssion should “merge” this previous Target data with the new data to be written to the Target.

For example, the below binding will update the value on every change of master_value. Howerver, if a user has already entered a custom value, unexpected binding reactivation will preserve it.

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

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

При неправильном проектировании такая повторно активируемая привязка может привести к потере введенных пользователем данных в ее Цели. Если это недопустимо, привязка должна учитывать ранее измененные данные в своей Цели (путем ссылки на свою собственную Цель из своего Выражения). Выражение должно "объединить" эти предыдущие данные Цели с новыми данными, которые будут записаны в Цель.

Например, приведенная ниже привязка будет обновлять value при каждом изменении master_value. Однако, если пользователь уже ввел value, неожиданная реактивация привязки сохранит его.

value = ({value} != {master_value}) ? {value} : {master_value}