在Setter之前调用的事件函数

ke3*_*pup 1 jsf valuechangelistener

我有以下下拉列表列出几辆汽车,我有它,以便它将所选项目的值存储在一个backbean变量中,并且一个事件被触发,因此其他下拉列表将根据此下拉控件的选定值填充,如下所示:

  <Td>
<h:selectOneMenu id="combocarList" 
    value="#{customerBean.selectedcar}"
    styleClass="comboStyle"
    valueChangeListener="#{customerBean.loadothercombos}"
    onchange="document.forms[0].submit()"
    >
    <f:selectItem
        itemLabel="-----------Select--------------"
        itemValue="None" />
    <f:selectItems value="#{customerBean.carsList}" />
</h:selectOneMenu>
 </Td>
Run Code Online (Sandbox Code Playgroud)

问题是当从上面的下拉列表中选择一个项目时,在导致问题的setter之前调用事件loadothercombos.

请注意,backbean客户定义为:

 <managed-bean-name>customerBean</managed-bean-name>
    <managed-bean-class>com.theway.customer</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
Run Code Online (Sandbox Code Playgroud)

我在调试中看到的行为,当我从下拉列表中选择一个项目时:

1) Getter is called for selectedcar
2) Loadothercombos is called  <------- This is called by the event
3) Setter is called for selectedcar
Run Code Online (Sandbox Code Playgroud)

在调用loadothercombos之前,我无法让它调用setter.任何见解将不胜感激.谢谢

Bal*_*usC 8

valueChangeListener为此目的使用一直是一种hacky方式.基本上,有两种方法可以解决这个"问题":

  1. 调用FacesContext#renderResponse()以便JSF立即转到渲染响应阶段,因此将跳过更新模型值(和调用操作)阶段:

    public void loadothercombos(ValueChangeEvent event) {
        selectedcar = (String) event.getNewValue();
        loadOtherCombosBasedOn(selectedcar);
        // ...
    
        FacesContext.getCurrentInstance().renderResponse();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将事件排队以调用操作阶段,以便在调用setter后执行其工作:

    public void loadothercombos(ValueChangeEvent event) {
        if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
            loadOtherCombosBasedOn(selectedcar);
        } else {
            event.setPhaseId(PhaseId.INVOKE_APPLICATION);
            event.queue();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

如果你正在使用JSF 2.0,那么有一个更容易的方法来处理这个<f:ajax>:

<h:selectOneMenu id="combocarList" 
    value="#{customerBean.selectedcar}"
    styleClass="comboStyle">
    <f:selectItem
        itemLabel="-----------Select--------------"
        itemValue="None" />
    <f:selectItems value="#{customerBean.carsList}" />
    <f:ajax listener="#{customerBean.loadOtherCombos}" render="otherComboIds" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)

public void loadothercombos() {
    loadOtherCombosBasedOn(selectedcar);
}
Run Code Online (Sandbox Code Playgroud)

具体问题无关:"组合框"是此下拉元素的不正确术语.组合框是一个可编辑的下拉列表,它基本上是<input type="text">和的组合<select>.你在那里只是单独呈现<select>,这些只是下拉,所以称之为好.