JSF - c:forEach不适用于递归方法

时间:2014-11-26 04:21:20

标签: java loops jsf recursion primefaces

我不会粘贴我的bean和模型类,因为代码一切正常。问题是dashboard.xhtml中的第一个循环(ui:repeat)工作正常,但comments.xhtml中的第二个循环(c:forEach)不起作用。

我测试了comments.xhtml中的#{comment.listComments.size()}确实返回大于零,这意味着c:forEach循环必须至少进行一次评论但不会发生。

Dashboard.xhtml

<h:dataTable id="commentout" value="#{messageBean.getComments(msg)}" var="com" rendered="#{not empty messageBean.getComments(msg)}">
    <h:column>
        <div>
            <b><i>#{com.owner.firstName} #{com.owner.lastName}:</i></b>
            <h:outputText value=" #{com}" />
            <h:commandLink style="margin: 0 0 0 10px; padding: 0;" styleClass="add_comment" value="Answer" action="#{commentBean.createCommentOnComment(com)}" />
        </div>

        <ui:repeat value="#{com.listComments}" var="comment" rendered="#{com.hasChildren}">
            <ui:include src="comments.xhtml" />
        </ui:repeat>
    </h:column>
</h:dataTable>

comments.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html">

    <div style="margin-left: 20px;">
        <div>
            <b><i>>#{comment.owner.firstName} #{comment.owner.lastName}:</i></b>
            <h:outputText value=" #{comment}" />
            <h:commandLink style="margin: 0 0 0 10px; padding: 0;" styleClass="add_comment" value="Answer" action="#{commentBean.createCommentOnComment(comment)}" />
        </div>

        <c:when test="#{comment.hasChildren}">
            #{comment.listComments.size()} <!-- Visual test for checking if it is really greater than zero -->
            <c:forEach items="#{comment.listComments}" var="comment">
                <ui:include src="comments.xhtml" />
            </c:forEach>
        </c:when>
    </div>
</ui:composition>

视觉问题: enter image description here

如果有人对递归方法有更好的了解,那么它也可以是正确答案......



更新:

如果我将<c:forEach />更改为<ui:repeat />而不是使用</c:when>使用“已呈现”属性,则会卡住并向我显示错误“溢出”。

为什么总结为<ui:repeat />的{​​{1}}会给我出现溢出错误?

2 个答案:

答案 0 :(得分:0)

感谢@BalusC,我从这个来源获得了成功解决方案的信息: c:forEach inside primefaces(e.g. p:panelgrid) inside ui:repeat

我编写的代码dashboard.xhtml只是所有代码的一部分。这部分是另外两个dataTables。我不知道dataTables是否也与此问题有关,但为了减少问题,我将其更改为<c:when><c:forEach>和简单<div>标记。

当我将所有<ui:include>更改为<c:forEach>标记时,问题就解决了。

如果你遇到像我这样的问题,那么以下是你应该采取的步骤来达到解决方案:
1)全部更改:

<h:dataTable value="#{messageBean.getComments(msg)}" var="com" rendered="#{not empty messageBean.getComments(msg)}">
    <h:column>
        <div>
        ...
        </div>
    </h:column>
</h:dataTable>

<c:when test="#{not empty messageBean.getComments(msg)}">
    <c:forEach items="#{messageBean.getComments(msg)}" var="com">
        <div>
        ...
        </div>
    </c:forEach>
</c:when>


2)全部改变:

<ui:repeat value="#{com.listComments}" var="comment" rendered="#{com.hasChildren}">
    <ui:include src="comments.xhtml" />
</ui:repeat>

<c:when test="#{com.hasChildren}">
    <c:forEach items="#{com.listComments}" var="subComment">
        <ui:include src="comments.xhtml">
            <ui:param name="comment" value="#{subComment}" />
        </ui:include>
    </c:forEach>
</c:when>


3)重要或只是建议
3.1)拆分<ui:include>标记并将<ui:param />标记放入其中!
3.2)对于<ui:include>标记使用不同的“var”参数而不是<ui:param />标记的“name”参数具有(示例在第2章中可以看到)

答案 1 :(得分:-1)

而不是<c:when test="#{comment.hasChildren}"> ... </c:when>使用<ui:fragment rendered="#{comment.hasChildren}"> ... </ui:fragment>而不是内部<c:forEach />使用另一个<ui:repeat />。 浏览网页或stackoverflow,您可以找到一些很好的文章,解释为什么将JSTL与Facelets混合会导致问题。

- 编辑 您必须将注释作为参数传递给包含文件:

<ui:include src="comments.xhtml">
   <ui:param name="comment" value="#{comment}" />
</ui:include>