3.6.2. Источники данных (устаревшее)
|
Это устаревший API. Новый API, доступный начиная с v.7.0, описан в разделе Компоненты данных. |
Источники данных обеспечивают работу связанных с данными (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()из источника данных хранящийся в нем экземпляр, можно напрямую читать и изменять значения его атрибутов.
|
Как правило, визуальный компонент привязывается к атрибуту, непосредственно принадлежащему сущности, находящейся в источнике данных. В приведенном выше примере компонент привязан к атрибуту Можно также привязать компонент к атрибуту связанной сущности, например к |
Источники данных также отслеживают изменения содержащихся в них сущностей, и могут отправлять измененные экземпляры обратно на 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.