CollectionContainer
Интерфейс CollectionContainer предназначен для работы с коллекцией экземпляров сущности. Это потомок интерфейса InstanceContainer.
CollectionContainer можно определить в XML-дескрипторе следующим образом:
<data readOnly="true">
<collection id="customersDc"
class="ui.ex1.entity.Customer">
<fetchPlan extends="_base"/>
<loader id="customersDl" >
<query>
<![CDATA[select e from uiex1_Customer e]]>
</query>
</loader>
</collection>
</data>
Методы
В CollectionContainer определены следующие методы:
-
setItems()- устанавливает коллекцию экземпляров сущности для контейнера. -
getItems()- возвращает неизменяемый список сущностей, хранимых в контейнере. Используйте этот метод для обхода коллекции, получения потока данных или экземпляра сущности по его позиции в списке. Если требуется получить экземпляр сущности по его идентификатору, используйте методgetItem(entityId). Например:@Autowired private CollectionContainer<Customer> customersDc; private Optional<Customer> findByName(String name) { return customersDc.getItems().stream() .filter(customer -> Objects.equals(customer.getLastName(), name)) .findFirst(); } -
getMutableItems()- возвращает изменяемый список сущностей, хранимых в контейнере. Все изменения списка, вызванные методамиadd(),addAll(),remove(),removeAll(),set(),clear(), публикуют событиеCollectionChangeEvent. Визуальные компоненты, подписанные на это событие, будут обновлены автоматически. Например:@Autowired private CollectionContainer<Customer> customersDc; private void createCustomer() { Customer customer = metadata.create(Customer.class); customer.setFirstName("John"); customer.setLastName("Doe"); customersDc.getMutableItems().add(customer); }Используйте метод getMutableItems()только тогда, когда необходимо изменить коллекцию. В остальных случаях предпочтительнее использоватьgetItems(). -
setItem()- устанавливает текущий экземпляр сущности для контейнера. Если передан неnull, переданный экземпляр должен уже иметься в коллекции, чтобы быть выбранным. Метод публикует событиеItemChangeEvent.Нужно учитывать, что визуальные компоненты, такие как
Table, не отслеживают событиеItemChangeEvent, публикуемое контейнером. Поэтому, если вам нужно выбрать строку в таблице, используйте методsetSelected()вместо методаsetItem()контейнера, содержащего коллекцию. Текущий экземпляр контейнера также будет изменен, так как контейнер отслеживает события компонента. Пример:@Autowired private CollectionContainer<Customer> customersDc; @Autowired private GroupTable<Customer> customersTable; private void selectFirstRow() { customersTable.setSelected(customersDc.getItems().get(0)); } -
getItem()- переопределяет аналогичный метод родительского интерфейсаInstanceContainerи возвращает текущий экземпляр. Если текущий экземпляр не задан, метод выбрасывает исключение. Используйте этот метод, если вы уверены, что для контейнера задан текущий экземпляр, в этом случае не требуется проверка возвращаемого значения наnull. -
getItemOrNull()- переопределяет аналогичный метод родительского интерфейсаInstanceContainerи возвращает текущий экземпляр. Если текущий экземпляр не задан, метод возвращаетnull. Всегда проверяйте полученное значение наnullперед использованием. -
getItemIndex(entityId)- возвращает позицию сущности с данным идентификатором в списке, возвращаемом методамиgetItems()иgetMutableItems(). Этот метод принимаетObject, поэтому вы можете передать как id сущности, так и экземпляр сущности целиком. Реализация контейнера поддерживает отображение идентификаторов на индексы, поэтому метод работает быстро даже с большими списками. -
getItem(entityId)- возвращает экземпляр сущности из коллекции по её идентификатору. Это ускоренный метод, который сначала получает позицию экземпляра с помощьюgetItemIndex(entityId), а затем возвращает экземпляр из списка, используя методgetItems().get(index). Метод выбрасывает исключение, если экземпляр с переданным id отсутствует в коллекции. -
getItemOrNull(entityId)- то же, что иgetItem(entityId), но возвращаетnull, если экземпляр с данным id отсутствует в коллекции. Всегда проверяйте полученное значение наnullперед использованием. -
containsItem(entityId)- возвращаетtrue, если экземпляр с данным id есть в коллекции. Это упрощенный метод, в котором на самом деле используетсяgetItemIndex(entityId). -
replaceItem(entity)- если экземпляр с тем же id есть в коллекции, он заменяется переданным экземпляром. Если таковой экземпляр отсутствует, переданный экземпляр будет добавлен к списку. Метод публикует событиеCollectionChangeEventс типомSET_ITEMилиADD_ITEMS, в зависимости от операции. -
setSorter()- задает для контейнера переданный сортировщик. Стандартной реализацией интерфейсаSorterявляетсяCollectionContainerSorter. Платформа задает его автоматически, если для контейнера определен загрузчик, однако можно создать и собственную реализацию, если необходимо. -
getSorter()- возвращает текущий сортировщик данного контейнера.
События
В дополнение к событиям InstanceContainer, интерфейс CollectionContainer позволяет зарегистрировать слушатели для события CollectionChangeEvent, которое вызывается при изменении коллекции сущностей, то есть при добавлении, удалении или замене элементов коллекции. Пример подписки на событие для контейнера, объявленного в XML с идентификатором customersDc:
@Subscribe(id = "customersDc", target = Target.DATA_CONTAINER)
public void onCustomersDcCollectionChange(CollectionContainer.CollectionChangeEvent<Customer> event) {
CollectionChangeType changeType = event.getChangeType(); (1)
Collection<? extends Customer> changes = event.getChanges(); (2)
// ...
}
| 1 | Тип изменения: REFRESH, ADD_ITEMS, REMOVE_ITEMS, SET_ITEM. |
| 2 | Коллекция сущностей, которые были добавлены или удалены из контейнера. Если тип изменения – REFRESH, то фреймворк не может определить, какие элементы были добавлены или удалены, поэтому данная коллекция пустая. |