Уважаемые разработчики платформы, выражаю признательность за обновление документации, в лице @krivopustov.
https://doc.cuba-platform.com/manual-7.0-ru/gui_data_comp_param.html
“Старый” механизм был очень хорош тем, что можно было передать параметр в экран или не передавать его…
В описанном примере в экран в любом случае должна быть установлена страна, иначе будет выброшено исключение. Что делать, если при использовании в качестве справочника, я не хочу передавать страну, а если в качестве лукапа - передаю? Подменять запрос в Dl на лету?
Была мысль использовать 2 Dl в одном Dc:
<collection id="districtsDc"
class="com.borets.wedb.entity.District"
view="district-view-with-country">
<loader id="districtsDl">
<query>
<![CDATA[select e from wedb$District e]]>
</query>
</loader>
<loader id="districtCountryDl">
<query>
<![CDATA[select e from wedb$District e where e.country = :country]]>
</query>
</loader>
</collection>
@Subscribe
private void onBeforeShow(BeforeShowEvent event) {
final DataLoader districtsFilteredByCountryDl = getScreenData().getLoader("districtCountryDl"); // При использовании инжекта, картина не изменяется.
if (this.country == null)
districtsDl.load();
else {
districtsFilteredByCountryDl.setParameter("country", this.country);
districtsFilteredByCountryDl.load();
}
}
Хотя в xsd я не получаю никаких ошибок, но в рантайм я получаю следующее исключение:
IllegalArgumentException: Loader 'districtCountryDl' not found
Полагаю, дело в том, что в этом методе вы не предполагали множественность лоадеров в контейнере.
protected void loadCollectionContainer(ScreenData screenData, Element element, @Nullable ScreenData hostScreenData) {
String containerId = getRequiredAttr(element, "id");
CollectionContainer<Entity> container;
if (checkProvided(element, hostScreenData)) {
//noinspection ConstantConditions
container = hostScreenData.getContainer(containerId);
} else {
container = factory.createCollectionContainer(getEntityClass(element));
loadView(element, getEntityClass(element), container);
}
screenData.registerContainer(containerId, container);
Element loaderEl = element.element("loader");
if (loaderEl != null) {
loadCollectionLoader(screenData, loaderEl, container, hostScreenData);
}
for (Element collectionEl : element.elements()) {
loadNestedContainer(screenData, collectionEl, container, hostScreenData);
}
}
Не знаю где это может выстрелить дальше, но может быть имеет смысл регистрировать все лоадеры в контейнере? Или вы предложите другое решение?
Выстрелит, как минимум, в методе loadAll
…
Очередной UPD:
Пока сделал вот так, но это как-то не очень…
@Subscribe
private void onBeforeShow(BeforeShowEvent event) {
if (this.country != null) {
districtsDl.setQuery(districtsDl.getQuery() + " where e.country = :country");
districtsDl.setParameter("country", this.country);
}
districtsDl.load();
}