以类似于here的方式使用抽象类来键入项集列表 of ui:repeat 。具体的子类重写用于的getType()方法 有条件地使用其特定属性呈现相应的子类型:
<!-- AbstractAction Rule#getActions() -->
<ui:repeat value="#{rule.actions}" var="action">
<!-- render when "action" instance of NotificationAction -->
<h:panelGroup rendered="#{action.type == 'notification'}">
... UI for NotificationAction properties
<h:panelGroup rendered="#{action.type == 'callback'}">
...
在Glassfish 3上运行时,列表中未定义的属性存在错误 其他子类的成员(PropertyNotFoundException),它发生在分支中 实际上是由呈现的属性关闭的。 c:forEach / c:选择似乎没有 适当。任何想法如何使渲染真正有条件并绕过 物业检查非常感谢!
谢谢。 哈罗
答案 0 :(得分:1)
经过一些测试后发现, ui:repeat 组件本身导致了错误。 尽管处于最终的 RenderResponse 阶段,它仍会尝试保存其子输入组件的状态。这是一个缩短的异常转储:
Caused by: javax.el.PropertyNotFoundException: ... The class FOO does not have a readable property 'BAR'.
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:104)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:343)
at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:428)
at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:522)
at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:926)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
此处忽略呈现的条件,EL解释器会抱怨不存在的属性。有一个简单的解决方案,使用 h:dataTable 迭代器而不是一列:
<h:dataTable value="#{rule.systemActions}" var="action">
<c:set var="name" value="#{action.class.simpleName.toLowerCase()}" />
<h:column>
<h:panelGroup rendered="#{name == 'notification'}">
<h:outputLabel for="phone">Phone:</h:outputLabel>
<h:inputText value="#{action.phone}" id="phone" />
</h:panelGroup>
<h:panelGroup rendered="#{name == 'reminder'}">
...
</h:panelGroup>
</h:column>
</h:dataTable>
干杯。
Jaro