2013-08-28 2 views
1

У меня есть два часа: selectOneMenu (1: Страны, 2: Города). Мне нужно загрузить все города из одной выбранной страны в города selectOneMenu с помощью ajax. Когда я изменяю значение стран selectOneMenu, мои города selectOneMenu принимает нулевое значение из countryBean.selectedCountry.Загрузка h: selectOneMenu в зависимости от другого h: selectOneMenu value

<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 всегда нуль. Каков правильный способ сделать это?

ответ

2

Один из многих правил которых JSF стартер необходимо знать:

  • Не делать бизнес-логику в метод получения.

После того, как вы пытаетесь исправить, сохраняя ваши методы геттер истинные методы получения и выполнения бизнес-логики в (пост) конструктора и/или действий (слушателя) методов (то есть не что-нибудь еще, чем просто return property; делать), то эта конкретная проблема исчезнет.

Вот зарезка пример:

<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); 
} 
+0

Я думаю, что стоит повторить объем бобов имеет важное значение, как упоминалось BalusC. @RequestScoped, например, приведет к вызову нового экземпляра класса при каждом отправке формы. Если произошел сбой проверки и вы вернетесь на ту же страницу, вы начнете сталкиваться с проблемами – Amin