3.5.3.4.4. Using Screen Parameters in Loaders
It is often required to load data in a screen depending on parameters passed to that screen. Below is an example of a browse screen which accepts a parameter and uses it to filter the loaded data.
Suppose we have two entities: Country
and City
. The City
entity has country
attribute which is a reference to Country
. The cities browser accepts a country instance and shows cities only of this country.
First, consider the cities screen XML descriptor. It’s loader contains a query with a parameter:
<collection id="citiesDc"
class="com.company.demo.entity.City"
view="_local">
<loader id="citiesDl">
<query>
<![CDATA[select e from demo_City e where e.country = :country]]>
</query>
</loader>
</collection>
The cities screen controller contains a public setter for the parameter and uses the parameter in BeforeShowEvent handler. Notice that the screen has no @LoadDataBeforeShow
annotation, because loading is triggered explicitly:
@UiController("demo_City.browse")
@UiDescriptor("city-browse.xml")
@LookupComponent("citiesTable")
public class CityBrowse extends StandardLookup<City> {
@Inject
private CollectionLoader<City> citiesDl;
private Country country;
public void setCountry(Country country) {
this.country = country;
}
@Subscribe
private void onBeforeShow(BeforeShowEvent event) {
if (country == null)
throw new IllegalStateException("country parameter is null");
citiesDl.setParameter("country", country);
citiesDl.load();
}
}
The cities screen can be opened from another screen passing a country as follows:
@Inject
private ScreenBuilders screenBuilders;
private void showCitiesOfCountry(Country country) {
CityBrowse cityBrowse = screenBuilders.screen(this)
.withScreenClass(CityBrowse.class)
.build();
cityBrowse.setCountry(country);
cityBrowse.show();
}