如何预先填充重复h:selectOneMenu?

时间:2010-06-23 18:25:40

标签: java jsf jstl myfaces

将每个订单一个点的工作表单修改为每个订单的多个点我遇到了预先填充h:selectOneMenu的问题。例外是java.lang.IllegalArgumentException: Value binding '#{spot.deliveryTypes}'of UISelectItems with component-path {Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId: /order.jsp][Class: javax.faces.component.html.HtmlForm,Id: pf][Class: javax.faces.component.html.HtmlSelectOneMenu,Id: _idJsp11][Class: javax.faces.component.UISelectItems,Id: _idJsp12]} does not reference an Object of type SelectItem, SelectItem[], Collection or Map but of type : null

旧的JSP代码:

<h:selectOneMenu value="#{order.deliveryType}" immediate="true">
 <f:selectItems value="#{order.deliveryTypes}" />
</h:selectOneMenu>

新的无效JSP代码:

<c:forEach var="spot" items="${order.spots}">
 <h:selectOneMenu value="#{spot.deliveryType}" immediate="true">
  <f:selectItems value="#{spot.deliveryTypes}" /> <%-- Works as empty list if this line removed --%>
 </h:selectOneMenu> <c:out value="${spot.name}"/><br/>
</c:forEach>

引入了新字段List<Spot> spots以及getter和setter。 List<SelectItem> getDeliveryTypes()已从托管bean类Order移至class Spot。

如何访问spot.deliveryTypes?将#更改为$没有帮助,因为value =不接受EL。

MyFaces 1.1.8

感谢。

1 个答案:

答案 0 :(得分:1)

JSTL和JSF并不是很好地携手合作。正如您对编码所期望的那样,JSP不会从上到下进行处理。更重要的是,JSTL首先从上到下处理JSP,然后将生成的结果交给JSF,以便从上到下进行自己的处理。这尤其使c:forEach无法满足此类要求。在这种特殊情况下,当JSF轮流处理JSP页面时,${spot}将不再存在。

您希望使用基于JSF UIData的组件而不是c:forEachc:forEach的完全替代JSF是Tomahawk's t:dataList。使用它,您的问题将得到解决。

如果你正在使用Facelets而不是JSP,你也可以使用它的ui:repeat