5.5.3. Источники данных
Источники данных обеспечивают работу связанных с данными (data-aware) компонентов.
Визуальные компоненты сами не обращаются к Middleware, а получают экземпляры сущностей из связанных источников данных. При этом один источник данных может обслуживать несколько визуальных компонентов, если им нужен один и тот же экземпляр или набор экземпляров.
Связь визуального компонента и источника данных проявляется в следующем:
-
При изменении пользователем значения в компоненте новое значение проставляется в атрибуте сущности, находящейся в источнике.
-
При изменении атрибута сущности из кода новое значение проставляется и отображается в визуальном компоненте.
-
Для слежения за вводом пользователя можно использовать как слушатель источника данных, так и слушатель значения визуального компонента - они срабатывают друг за другом.
-
При необходимости прочитать или записать значение атрибута сущности в коде предпочтительнее использовать источник данных, а не компонент. Рассмотрим пример чтения атрибута:
@Inject private FieldGroup fieldGroup; @Inject private Datasource<Order> orderDs; @Named("fieldGroup.customer") private PickerField customerField; public void init(Map<String, Object> params){ Customer customer; // Get customer from component: not for common use Component component = fieldGroup.getFieldNN("customer").getComponentNN(); customer = ((HasValue)component).getValue(); // Get customer from component customer = customerField.getValue(); // Get customer from datasource: recommended customer = orderDs.getItem().getCustomer(); }
Как видно из примера, работа со значениями атрибутов сущностей через компонент - не самый прямолинейный способ. В первом случае он требует приведения типа и указания поля FieldGroup в виде строки. Второй пример более безопасный и прямой, но он требует знания ещё и типа поля, которое должно быть инжектировано в контроллер. В то же время, получив методом
getItem()
из источника данных хранящийся в нем экземпляр, можно напрямую читать и изменять значения его атрибутов.
Warning
|
Как правило, визуальный компонент привязывается к атрибуту, непосредственно принадлежащему сущности, находящейся в источнике данных. В приведенном выше примере компонент привязан к атрибуту Можно также привязать компонент к атрибуту связанной сущности, например к |
Источники данных также отслеживают изменения содержащихся в них сущностей, и могут отправлять измененные экземпляры обратно на Middleware для сохранения в базе данных.
Рассмотрим основные интерфейсы источников.
-
Datasource − простейший источник данных, предназначенный для работы с одним экземпляром сущности. Экземпляр устанавливается методом
setItem()
и доступен черезgetItem()
.Стандартной реализацией такого источника является класс
DatasourceImpl
, который используется, например, как главный источник данных в экранах редактирования сущностей. -
CollectionDatasource − источник данных, предназначенный для работы с коллекцией экземпляров сущности. Коллекция загружается при вызове метода
refresh()
, ключи экземпляров доступны через методgetItemIds()
. МетодsetItem()
устанавливает, аgetItem()
возвращает "текущий" экземпляр коллекции, т.е., например, соответствующий выбранной в данный момент строке таблицы.Способ загрузки коллекции сущностей определяется реализацией. Наиболее типичный - загрузка с Middleware через DataManager, при этом для формирования JPQL запроса используются методы
setQuery()
,setQueryFilter()
.Стандартной реализацией такого источника является класс
CollectionDatasourceImpl
, который используется в экранах, отображающих списки сущностей.-
GroupDatasource − подвид
CollectionDatasource
, предназначенный для работы с компонентом GroupTable.Стандартной реализацией является класс
GroupDatasourceImpl
. -
HierarchicalDatasource − подвид
CollectionDatasource
, предназначенный для работы с компонентами Tree и TreeTable.Стандартной реализацией является класс
HierarchicalDatasourceImpl
.
-
-
NestedDatasource - источник данных, предназначенный для работы с экземплярами, загруженными в атрибуте другой сущности. При этом источник, содержащий сущность-хозяина, доступен методом
getMaster()
, а мета-свойство, соответствующее атрибуту хозяина, содержащему экземпляры данного источника, доступно через методgetProperty()
.Например, в источнике
dsOrder
установлен экземпляр сущностиOrder
, содержащий ссылку на экземплярCustomer
. Тогда для связи экземпляраCustomer
с визуальными компонентами достаточно создатьNestedDatasource
, у которого хозяином являетсяdsOrder
, а мета-свойство указывает на атрибутOrder.customer
.-
PropertyDatasource - подвид
NestedDatasource
, предназначенный для работы с одним экземпляром или коллекцией связанных сущностей, не являющихся встроенными (embedded).Стандартные реализации: для работы с одним экземпляром -
PropertyDatasourceImpl
, для работы с коллекцией -CollectionPropertyDatasourceImpl
,GroupPropertyDatasourceImpl
,HierarchicalPropertyDatasourceImpl
. Последние реализуют также интерфейсCollectionDatasource
, однако некоторые его нерелевантные методы, связанные с загрузкой, например,setQuery()
, выбрасываютUnsupportedOperationException
. -
EmbeddedDatasource - подвид
NestedDatasource
, содержащий экземпляр встроенной сущности.Стандартной реализацией является класс
EmbeddedDatasourceImpl
.
-
-
RuntimePropsDatasource − специфический источник, предназначенный для работы с динамическими атрибутами сущностей.
Как правило, источники данных объявляются декларативно в секции dsContext
дескриптора экрана.
- Автоматическое обновление CollectionDatasource
-
При открытии экрана, его визуальные компоненты, соединенные с источниками типа
CollectionDatasource
, заставляют эти источники загрузить данные. В результате, таблицы отображают данные сразу после открытия экрана, без всякого дополнительного действия пользователя. Если вы хотите предотвратить автоматическую загрузку, то установите параметр экранаDISABLE_AUTO_REFRESH
вtrue
в методеinit()
этого экрана, или передайте его из вызывающего кода. Данный параметр определен в перечисленииWindowParams
, поэтому он может быть задан следующим образом:@Override public void init(Map<String, Object> params) { WindowParams.DISABLE_AUTO_REFRESH.set(params, true); }
В этом случае, источники данных типа
CollectionDatasource
будут загружены только когда будет вызван их методrefresh()
. Это может быть сделано как кодом приложения, так и в случае, если пользователь нажмет кнопку Search компонента Filter.