我有以下下拉列表列出几辆汽车,我有它,以便它将所选项目的值存储在一个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。任何见解将不胜感激。感谢
答案 0 :(得分:8)
为此目的使用valueChangeListener
一直是一种愚蠢的方式。基本上,有两种方法可以解决这个“问题”:
调用FacesContext#renderResponse()
以便JSF立即转到渲染响应阶段,因此将跳过更新模型值(和调用操作)阶段:
public void loadothercombos(ValueChangeEvent event) {
selectedcar = (String) event.getNewValue();
loadOtherCombosBasedOn(selectedcar);
// ...
FacesContext.getCurrentInstance().renderResponse();
}
将事件排队以调用操作阶段,以便在调用setter后执行其工作:
public void loadothercombos(ValueChangeEvent event) {
if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
loadOtherCombosBasedOn(selectedcar);
} else {
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
event.queue();
}
}
如果您正在使用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}"