【问题标题】:JSF 2 ui:repeat: group every n items inside a divJSF 2 ui:repeat: 对 div 中的每 n 个项目进行分组
【发布时间】:2012-05-15 22:34:52
【问题描述】:

给定一个我想在这样的页面上排列的集合:

<!-- Group 0 -->
<div style="float:left;">
    <div><!-- Item 0 --></div>
    <div><!-- Item 1 --></div>

    <!-- ... -->

    <div><! -- Item n - 1 --></div>
</div>
<!-- Group 1 -->
<div style="float:left;">
    <div><!-- Item n     --></div>
    <div><!-- Item n + 1 --></div>

    <!-- ... -->

    <div><! -- Item 2n - 1 --></div>
</div>

<!-- ... -->

<!-- Group g -->
    <div><!-- Item gn     --></div>
    <div><!-- Item gn + 1 --></div>

    <!-- ... -->

    <div><! -- Item (g + 1)n - 1 --></div>
</div>

除了创建自定义组件之外,我是否可以在 ui:repeat 或通过其他技术(最好)使用某种技巧来做到这一点?

【问题讨论】:

    标签: java jsf jsf-2 uirepeat


    【解决方案1】:

    您可以通过varStatus 属性检查当前循环轮次,并在必要时打印中介&lt;/div&gt;&lt;div style="float: left;"&gt;

    例如每 3 项:

    <div style="float: left;">
        <ui:repeat value="#{bean.list}" var="item" varStatus="loop">
            <h:outputText value="&lt;/div&gt;&lt;div style='float: left;'&gt;" escape="false" rendered="#{not loop.first and loop.index % 3 == 0}" />
            <div>#{item}</div>
        </ui:repeat>
    </div>
    

    请注意,不能将其作为纯 HTML 包装在 &lt;h:panelGroup&gt; 中,因为这会导致 XML 格式不正确,因此 &lt;h:outputText escape="false"&gt; 会将它们作为 XML 实体。


    更新根据 cmets,这是一种替代方法,将 &lt;div&gt;s 仅定义一次,这可能不太容易混淆:

    <ui:repeat value="#{bean.list}" var="item" varStatus="loop">
        <h:outputText value="&lt;div style='float: left;'&gt;" escape="false" rendered="#{loop.index % 3 == 0}" />
        <div>#{item}</div>
        <h:outputText value="&lt;/div&gt;" escape="false" rendered="#{loop.last or (loop.index + 1) % 3 == 0}" />
    </ui:repeat>
    

    【讨论】:

    • 您注意到输出文本中的&amp;lt;/div&amp;gt;了吗?这将关闭组。我计算了偶数个打开和关闭 divs 标签,而不是奇数。
    • 是的,我可以看到你做了什么,这就是为什么我仔细看了很久,还没有编辑。这很聪明。问题是,您需要打开第一个组。
    • 啊,列表可能是空的?然后将所有内容都包含在&lt;h:panelGroup rendered="#{not empty bean.list}"&gt; 中。如有必要,将其全部放在一个组合中以隐藏所有冗长。
    【解决方案2】:

    如果可能,我会在服务器端中断收集:

    <ui:repeat value="#{groups}" var="group">
      <div style="float:left;">
        <ui:repeat value="#{group.items}" var="item">
          <div>#{item.content}</div>
        </ui:repeat>
      </div>
    </ui:repeat>
    

    另一种选择可能是(尚未测试,尤其不确定尺寸行为):

    <ui:repeat value="#{items}" var="group" varStatus="status" step="n">
      <div style="float:left;">
        <ui:repeat value="#{items}" var="item" offset="#{status.index}" size="#{status.index + n}">
          <div>#{item.content}</div>
        </ui:repeat>
      </div>
    </ui:repeat>
    

    编辑:第二个版本已被替换

    【讨论】:

    • +1 作为您的第一个解决方案,因为这会起作用,几分钟前我想到了类似的东西。我的计划是使用自定义函数来应用分组。不过,我不确定您的第二个解决方案是否有效。至少,任何 IDE 都会讨厌它。
    • 后者仅在 JSP 中有效,在 Facelets 中无效,因为它在语法上是无效的 XML。但是在 JSP 中你没有&lt;ui:xxx&gt; 标签,只有&lt;c:forEach&gt;&lt;c:if&gt;
    • 您更新的第二个示例不会产生所需的 HTML 输出。
    • 使用了另一种方法。现在应该没事了。
    • 如果列表有 size%n!=0 个项目,这将不起作用。然后嵌套循环的size 将大于实际剩余大小。
    猜你喜欢
    • 2021-10-08
    • 1970-01-01
    • 2017-07-29
    • 2021-11-14
    • 2014-01-03
    • 2013-03-19
    • 1970-01-01
    • 2011-07-19
    • 2021-09-16
    相关资源
    最近更新 更多