JSF ui:repeat 标签内子类的条件渲染

发布于 2024-10-20 22:56:32 字数 810 浏览 0 评论 0原文

以类似于此处的方式,我正在使用抽象用于键入项目集列表的类 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),发生在以下分支中: 实际上是由 rendered 属性关闭的。 c:forEach/c:choose 似乎没有 合适的。任何想法如何使渲染真正有条件并绕过 高度赞赏财产检查!

谢谢。 哈罗

in a way similar to here I am using an abstract class to type the item set list
of ui:repeat. Concrete subclasses override the getType() method, that is used to
conditionally render the respective subtype with its particular properties:

<!-- 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'}"> 
    ...

When run on Glassfish 3 there is an error about properties not being defined on list
members of other subclasses (PropertyNotFoundException), which occurs in a branch that
is actually switched off by the rendered property. c:forEach/c:choose do not seem
appropriate. Any ideas how to make the rendering really conditional and bypass the
property checking are highly appreciated!

Thank you.
Jaro

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡墨 2024-10-27 22:56:32

经过一些测试后发现,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)

这里 rendered 条件被忽略,并且 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>

干杯。

哈罗

after some testing it turned out, that the ui:repeat component itself caused the error.
Despite being in the final RenderResponse phase it tries to save the status of its child input components. Here a shortened exception dump:

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)

Hereby the rendered condition is ignored and the EL interpreter complains about non-existent properties. There is a simple solution by using the h:dataTable iterator with a single column instead:

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

Cheers.

Jaro

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文