Загрузка h:selectOneMenu в зависимости от другого значения h:selectOneMenu
У меня есть два h:selectOneMenu (1: страны, 2: города). Мне нужно загрузить все города из одной выбранной страны в городах выберите OneMenu, используя ajax. Когда я изменяю значение стран selectOneMenu, мои города selectOneMenu принимает нулевое значение из countryBean.selectedCountry.
<h:panelGrid columns="2">
<h:outputLabel for="countries" value="Countries: " />
<h:selectOneMenu converter="omnifaces.SelectItemsConverter"
id="countries" required="true" value="#{countryBean.selectedCountry}">
<f:selectItem itemLabel="Choose country" />
<f:selectItems value="#{countriesBB.findAllCountries()}"
var="country" itemLabel="#{country.name}" />
<f:ajax event="change" render="cities" />
</h:selectOneMenu>
<h:outputLabel for="cities"
value="Cities: " />
<h:selectOneMenu converter="omnifaces.SelectItemsConverter"
id="cities" required="true"
value="#{cityBean.selectedCity}">
<f:selectItem itemLabel="Choose city" />
<f:selectItems value="#{cityBean.findAllCitiesByCountry(countryBean.selectedCountry)}"
var="city" itemLabel="#{city.name}" />
</h:selectOneMenu>
</h:panelGrid>
Это метод, который находит города:
public List<city> findAllCitiesByCountry(Country country) {
List<City> cities = null;
try {
cities = citiesService.findAllCitiesByCountry(country);
} catch (Exception exception) {
logger.debug("Error finding cities.", exception);
}
return cities;
}
Я получаю исключение NullPointerException, потому что countryBean.selectedCountry всегда имеет значение null. Как правильно это сделать?
1 ответ
Одно из многих правил, которые JSF-стартер должен знать:
- Не занимайтесь бизнес-логикой в методе получения.
Как только вы попытаетесь исправить это, сохраняя ваши методы получения истинными методами получения (то есть не делайте ничего, кроме return property;
) и выполнение бизнес-логики в (post) конструкторе и / или action (listener) методах, тогда эта конкретная проблема исчезнет.
Вот начальный пример:
<h:selectOneMenu value="#{bean.country}">
<f:selectItems value="#{bean.countries}" ... />
<f:ajax listener="#{bean.changeCountry}" render="cities" />
</h:selectOneMenu>
<h:selectOneMenu id="cities" value="#{bean.city}">
<f:selectItems value="#{bean.cities}" ... />
</h:selectOneMenu>
С чем-то вроде этого в @ViewScoped
боб:
private Country country; // +getter+setter
private City city; // +getter+setter
private List<Countries> countries; // +getter
private List<Cities> cities; // +getter
@EJB
private SomeService service;
@PostConstruct
public void init() {
countries = service.getCountries();
}
public void changeCountry() {
cities = service.getCities(country);
}