Здравствуйте!
Studio и Jmix 2.4.3.
Есть некая базовая сущность, допустим Entity, у сущности помимо прочего есть поле Status
Есть несколько экранов, предположим 8, для отображения списка сущностей по статусам. Каждый из этих экранов имеет genericFilter и dataGird. Было несколько неудобно, так как приходилось копировать один и тот же код фильтра и грида во все 8 экранов.
С выходом fragments мелькнула возможность решить этот вопрос, создав фрагмент с компонентом GenericFilter и фрагмент с компонентом DataGrid, указав для атрибута <collection> provided = true. И действительно оно сработало, xml экрана списка значительно похудел, когда его заменили этими двумя фрагментами, а для изменения/добавления пропертей фильтра или колонок грида достаточно поменять их во фрагменте.
Но тут дело дошло ещё до одного экрана, где есть элемент TabSheet, который содержит две вкладки Tab. У каждой вкладки Tab есть те же GenericFilter и DataGrid что и в остальных экранах. То есть, в xml экрана определены 2 коллекции со своим названием, например EntityDc1 и EntityDc2, со своими лоудерами EntityDl1 и EntityDl2. Соответственно надо каким-то образом указать фрагментам, что для вкладки Tab1 тебе нужен EntityDc1 и EntityDl1, а для вкладки Tab2 - EntityDc2 и EntityDl2.
Для фрагмента с dataGrid это удалось реализовать, устанавливая свой контейнер в каждый фрагмент по его id.
Спойлер
@Subscribe
public void onInit(final InitEvent event) {
gridFragment1.setDataContainer(EntityDc1);
gridFragment2.setDataContainer(EntityDc2);
}
@FragmentDescriptor("common-grid-fragment.xml")
public class CommonGridFragment extends Fragment<DataGrid<Entity>> {
@ViewComponent
private DataGrid<Entity> entitiesDataGrid;
public void setDataContainer(CollectionContainer<Entity> container) {
entitiesDataGrid.setItems(container.getItems());
}
}
Однако с фрагментом фильтра это никак сделать не удалось. С виду всё было просто, компонент genericFilter имеет метод setDataLoader(DataLoader dataLoader), то есть достаточно передать свои CollectionLoader<Entity> во фрагменты, но этот метод имеет следующую реализацию:
Спойлер
public void setDataLoader(DataLoader dataLoader) {
checkState(this.dataLoader == null, "DataLoader has already been initialized");
checkNotNull(dataLoader);
this.dataLoader = dataLoader;
this.initialDataLoaderCondition = dataLoader.getCondition();
LogicalFilterComponent<?> rootLogicalFilterComponent = emptyConfiguration.getRootLogicalFilterComponent();
rootLogicalFilterComponent.setDataLoader(dataLoader);
rootLogicalFilterComponent.setAutoApply(autoApply);
}
То есть при попытки установить переданный из экрана loader в genericFilter вылетала ошибка метода. Убрать из фрагмента контейнер нельзя, так как у компонента genericFilter атрибут dataLoader обязателен, как отменить инициализацию тоже неизвестно, из экрана loader пытался устанавливать в методе onInit.
Никакие попытки связать загрузчики/коллекции из экрана и из фрагмента не увенчались успехом, фильтр не работал, вылетали различные ошибки.
Подскажите, есть ли какое решение?
Ссылка на проект-заготовку: