OneMenu 不保留更改的值

OneMenu not persisting changed value

在 post (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 为空。

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,这也应该解释您遇到的第二个问题。

关于第三期,看这个Q/A:

  1. Why is the getter called so many times by the rendered attribute?
  2. Why JSF calls getters multiple times