在我的帖子(Hibernate Primefaces AutoComplete text)之后,我稍微切换了实现。但现在我遇到了一个问题。
即使我使用AJAX事件,我也不会保留选定的值以填充第二个下拉列表。
我的CREATE.XHTML
<h:head></h:head>
<ui:debug rendered="true"/>
<body>
<h:form id="createAddressForm" prependId="true">
<!-- <p:messages autoUpdate="true" /> -->
<p:growl id="msgs" showDetail="true" />
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
<p:outputLabel for="countryDropDown" value="Country" />
<p:selectOneMenu id="countryDropDown" value="#{addressController.selectedIsoCountry}" >
<p:ajax listener="#{addressController.onCountryChange}" update="stateDropDown" />
<f:selectItem itemValue="" itemLabel="Select a country"/>
<f:selectItems value="#{addressController.countryMap}" />
</p:selectOneMenu>
<p:outputLabel for="stateDropDown" value="State" />
<p:selectOneMenu id="stateDropDown" value="#{addressController.state}" >
<f:selectItem itemValue="" itemLabel="Selecione a State" />
<f:selectItems value="#{addressController.stateMap}" />
</p:selectOneMenu>
</h:panelGrid>
</h:form>
</body>
</html>
这是AddressController.java
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;
import br.com.azulseguros.ejb.CountryEJB;
import br.com.azulseguros.entity.Country;
import br.com.azulseguros.entity.State;
@SessionScoped
@Named
public class AddressController {
@EJB
private CountryEJB countryEJB;
private String selectedIsoCountry = null;
private State state = null;
private Map<String, String> countryMap = null;
private Map<String, String> stateMap = null;
@PostConstruct
private void init() {
Map<String, String> retorno = new TreeMap<String, String>();
for (Country _tmp : countryEJB.findAll()) {
retorno.put(_tmp.getName(), _tmp.getIso());
}
countryMap = retorno;
}
public Map<String, String> getCountryMap() {
return countryMap;
}
public Map<String, String> getStateMap() {
return stateMap;
}
public String getSelectedIsoCountry() {
return selectedIsoCountry;
}
public State getState() {
return state;
}
public void setSelectedIsoCountry(String selectedIsoCountry) {
this.selectedIsoCountry = selectedIsoCountry;
}
public void setState(State state) {
this.state = state;
}
public void setCountryMap(Map<String, String> countryMap) {
this.countryMap = countryMap;
}
public void setStateMap(Map<String, String> stateMap) {
this.stateMap = stateMap;
}
public void onCountryChange() {
setStateMap(getStatesFromSelectedCountry());
}
private Map<String, String> getStatesFromSelectedCountry() {
Map<String, String> retorno = new TreeMap<String, String>();
if (selectedIsoCountry != null && !selectedIsoCountry.equals("")) {
for (State _tmp : countryEJB.findByIso(selectedIsoCountry).getStates()) {
retorno.put(_tmp.getName(), _tmp.getFu());
}
}
return retorno;
}
}
用于查找所有国家/地区的EJB负责人工作正常。这有很多问题,我不知道如何解决它。 1 - 我第一次调用页面后,它调用init方法10次; 2 - 之后它引发了方法getStatesFromSelectedCountry,甚至没有从第一个下拉列表中选择任何国家,然后再次唤起init方法; 3 - 当我选择一个国家时,它会唤起init方法的7倍,然后是getStatesFromSelectedCountry(),但selectedIsoCountry是null。
答案 0 :(得分:1)
bean的init
方法被多次调用,因为您已将bean定义为使用javax.inject.Named
的CDI bean,没有范围,以及使用javax.faces.bean.SessionScoped
作为JSF Managed Bean;如果您打算使用CDI bean,只需将后一个注释替换为javax.enterprise.context.SessionScoped
即可。见Why are there different bean management annotations
从CDI的角度来看,bean默认为RequestScoped
,这也应该解释您遇到的第二个问题。
关于第三个问题,请参阅此问答: