MyTetra Share
Делитесь знаниями!
Источники данных
Время создания: 30.01.2020 08:47
Раздел: INFO - Development - CUBA
Запись: wwwlir/Tetra/master/base/158034525109h4k51n4q/text.html на raw.githubusercontent.com

Источники данных

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


Как правило, визуальный компонент привязывается к атрибуту, непосредственно принадлежащему сущности, находящейся в источнике данных. В приведенном выше примере компонент привязан к атрибуту customer сущности Order.

Можно также привязать компонент к атрибуту связанной сущности, например к customer.name. В этом случае компонент будет корректно отображать значение атрибута name, но при его изменении пользователем слушатели источника данных вызваны не будут, и изменения не будут сохранены. Поэтому привязывать компонент к атрибутам второго и более порядка имеет смысл только для отображения, например в Label , колонке Table или установив для TextField свойство editable = false.

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

Рассмотрим основные интерфейсы источников.

Рисунок 22. Интерфейсы источников данных

  • 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 .

 
MyTetra Share v.0.65
Яндекс индекс цитирования