Иногда требуется загружать и отображать данные, которые зависят от других данных в том же экране. К примеру, на скриншоте ниже таблица слева отображает список заказов, а таблица справа - список строк выбранного заказа. Список справа обновляется каждый раз, когда меняется выбранный заказ в таблице слева.
В нашем примере сущность Order
содержит атрибут orderLines
, который является коллекцией с отношением one-to-many. Самый простой способ реализации экрана - загружать список заказов с представлением, содержащим атрибут orderLines
, и использовать property container для работы со списком зависимых строк. Затем мы связываем левую таблицу с родительским контейнером, а правую - с контейнером свойства.
Однако этот подход может иметь последствия для производительности, ведь мы загружаем все строки для всех заказов из левой таблицы, несмотря на то, что в один момент времени отображаются строки только для одного выбранного заказа. При этом чем длиннее список заказов, тем больше ненужных данных будет загружено, и вероятность того, что пользователь захочет просмотреть все строки, очень мала. Поэтому мы рекомендуем использовать контейнеры свойств и расширенные представления только тогда, когда нужно загрузить единственный экземпляр родительской сущности: например, в экране редактирования одного заказа.
Кроме того, родительская сущность может не иметь прямого атрибута, указывающего на зависимую сущности. В этом случае подход с использованием контейнера свойств совсем не подходит.
Наилучшей практикой организации отношений между данными в экране является использование запросов с параметрами. Зависимый загрузчик содержит запрос с параметром, который связывает данные с родительским контейнером, и когда меняется текущий экземпляр в родительском контейнере, мы передаём его в качестве параметра и вызываем зависимый загрузчик.
Рассмотрим пример экрана, в котором есть две зависимых пары контейнер/загрузчик и привязанные к ним таблицы для отображения данных.
link:../../../../../../source/gui/data_comp/data_comp_dep_1.xml[role=include]
-
Родительский контейнер и загрузчик.
-
Дочерний контейнер и загрузчик.
-
Основная таблица.
-
Зависимая таблица.
link:../../../../../../source/gui/data_comp/data_comp_dep_1.java[role=include]
-
Класс контроллера экрана не содержит аннотации
@LoadDataBeforeShow
, поэтому загрузчики не будут вызваны автоматически. -
Родительский загрузчик вызывается обработчиком
BeforeShowEvent
. -
В обработчике родительского контейнера
ItemChangeEvent
передаём параметр в зависимый загрузчик и вызываем его.
Tip
|
Фасет DataLoadCoordinator позволяет устанавливать связи между компонентами данных декларативно без написания кода на Java. |