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 , то фреймворк не может определить, какие элементы были добавлены или удалены, поэтому данная коллекция пустая. |