在Setter之前调用的事件函数

时间:2011-10-11 06:51:48

标签: 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>

问题是当从上面的下拉列表中选择一个项目时,在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>

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

1) Getter is called for selectedcar
2) Loadothercombos is called  <------- This is called by the event
3) Setter is called for selectedcar

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

2 个答案:

答案 0 :(得分:8)

为此目的使用valueChangeListener一直是一种愚蠢的方式。基本上,有两种方法可以解决这个“问题”:

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

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

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

  3. 如果您正在使用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>
    

    public void loadothercombos() {
        loadOtherCombosBasedOn(selectedcar);
    }
    

    对具体问题

    无关:“组合框”是此下拉元素的错误术语。组合框是可编辑下拉列表,它基本上是<input type="text"><select>的组合。你在那里只是单独渲染<select>而这些只是下拉,所以就这样称呼它们。

答案 1 :(得分:1)

  

问题是当从上面的下拉列表中选择一个项目时,该事件   在setter

之前调用loadothercombos

嗯,是预期的JSF生命周期行为。在成功转换/验证提交的值之后,仅在提交的值与初始值不同时,在验证阶段调用valueChangeListener="#{customerBean.loadothercombos}"。在调用valueChangeListener之后,JSF将继续转换/验证下一个UIInput,并且当JSF实现确定数据有效时,然后继续调用您的setter方法Update Model Values Phase下一个value="#{customerBean.selectedcar}"