【问题标题】:Dynamic ui:include inside ui:repeat. Is there a simple solution?动态 ui:include 内部 ui:repeat。有简单的解决方案吗?
【发布时间】:2010-07-29 12:36:59
【问题描述】:

我想动态选择一个 facelet 来呈现我的数据列表中的一些项目。第一次尝试是:

但它不起作用,因为 ui:include 的 src 被评估得太早了。 facelet 信息是真正动态的,所以我不能使用 c:forEach (也不建议与 facelet 混合使用)。我想这一切都归结为找到一个基于组件的 ui:include 替代方案。

有这样的东西还是我需要自己写?

【问题讨论】:

  • 多年来,我们一直在为同样的问题苦苦挣扎。我想知道 mrembisz 你有没有用 JSF 2 找到更好的解决方案?如果不能,您可以分享您的自定义解决方案吗?
  • @cyberoblivion 我们已经实现了我们自己的包含组件并调整了 UIRepeat 来使用它——主要是为了允许多个嵌套级别。它仍然适用于我们的生产系统。但我们还是离开了 JSF。
  • 所以该解决方案对其他人没有用处,或者您被禁止共享代码?我对代码很感兴趣。
  • @cyberoblivion 你可以试试这些课程。需要注册这些组件,以便让这一切正常工作并非易事:pastebin.com/FSfYWehfDynamicInclude pastebin.com/Lpf4UxxQUIRepeat(我认为已编辑 JSF 2.0.6 代码)pastebin.com/bKk701xUDynamicIncludeHandler
  • 这看起来正是我所需要的。先生,您是绅士和学者!谢谢!

标签: java jsf facelets


【解决方案1】:

我想我找到了您一直在寻找的相对简单的解决方案。

我也是从 ui:include 开始的即使用户交互改变了视图中的内容,就像我认为的那样。它看起来像这样:

<c:forEach var="thing" items="#{view.things}">
        <ui:include src="#{thing.renderComponent}">
            <ui:param name="thing" value="#{thing}"/>
        </ui:include>
</c:forEach>

但是,我的 ui:param 不起作用 - 我包含的每个组件都传递了相同的“事物”/对象,即使我们已成功使用不同的事物/对象来动态包含不同的组件。

那时我发现this 帖子启发我将我的 ui:include 包装在 f:subview 中。现在,使用以下代码一切正常:

<c:forEach var="thing" items="#{view.things}" varStatus="loop">
    <f:subview id="thing_#{loop.index}">
        <ui:include src="#{thing.renderComponent}">
            <ui:param name="thing" value="#{thing}"/>
        </ui:include>
    </f:subview>
</c:forEach>

【讨论】:

    【解决方案2】:

    c:forEach 会解决,为什么不能用呢?

    关于该问题的有趣文章: https://rogerkeays.com/jsf-c-foreach-vs-ui-repeat

    【讨论】:

    • 谢谢,但是 c:forEach 在构建视图时被评估一次。在我的情况下,#{panels} 下的内容可能会在用户与页面交互时发生变化。
    • 将此标记为答案:由于性能影响,它对我不起作用,但对大多数人来说都很好。暂时使用自定义动态包含。
    【解决方案3】:

    我记得我曾尝试使用自定义标签和 FaceletHandler 等来做类似的事情。最后,所有的渲染时间小问题都让它变得不值得。请注意,我曾经(现在仍然是 :-(...) 使用 jsf 1.1 的 facelets,所以不确定这在以后的版本中是否更好。

    您需要处理多少动态/多少不同的 facelet?我问的原因是你可以(借用编译器向导的一个术语)展开你的循环。而不是

    <ui:repeat value="#{panels}" var="panel">
      <ui:include src="#{panel.facelet}">
    </ui:repeat>
    

    你可以的

    <custom:panelOneFacelet rendered="#{hasPanel1}" />
    <custom:panelTwoFacelet rendered="#{hasPanel2}" />
    <!-- etc... -->
    

    在你的 facelet 中,你会有类似的东西:

    <c:if test="#rendered" >
        <!-- EVERYTHING IN THE FACELET HERE!!!-->
    </c:if>
    

    这种低技术方法适用于小型受控集合,但如果您有一个非常大且多变的 facelets 集合,这可能行不通。

    我可能会问为什么,b/c 有时在了解高级别的情况下,SO 大师可能会提出更简单的想法来实现相同的目标

    【讨论】:

    • 基本上我们渲染一个业务表单,它作为数据字段树提供给我们。您在这里描述的是我们的第一次尝试,但结果证明它非常消耗资源,因为在每个节点中我们都有一整套可能的渲染选项。我们最终实现了我们自己的包含标签 + 组件,它工作得很好,但由于复杂性和 jsf 内部结构,维护起来确实很痛苦。我们大约在 3 年前就这样做了,现在计划迁移到 jsf2。我希望此时出现一些开箱即用的替代方案。
    • 嗯 .. 不确定我理解...所以你有像图书馆 { location, name, List books} where Book { name, isbn, Author} where Author {name, age, ..} 类似的东西?你想要那种结构来生成表单字段树?...我一定有这个错误,是吗?..这对我来说似乎太复杂了,我会将所有这些分解为不同的表单和 bean等等……
    • 你说得对,这正是我们所拥有的,直到运行时我们才知道记录结构。正如我所说,我们有一个可行但相当复杂的解决方案。我想调查删除我们的自定义 jsf 包含逻辑的可能性。
    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多