JSF中的子类的条件呈现ui:repeat标记

时间:2011-03-10 09:20:12

标签: jsf-2 polymorphism rendering

以类似于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:选择似乎没有  适当。任何想法如何使渲染真正有条件并绕过  物业检查非常感谢!

谢谢。     哈罗

1 个答案:

答案 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