Я не буду вставлять свои бобы и классы моделей, потому что все в порядке с кодом. Проблема в том, что первый цикл (ui: repeat) в dashboard.xhtml работает нормально, но второй цикл (c: forEach) в комментариях. Xhtml не работает.
Я тестировал, что # {comment.listComments.size()} в комментариях. Xhtml действительно возвращает больше нуля, что означает, что цикл 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>
Визуальная проблема:
ИЛИ
Если у кого-то есть лучшее представление о методе рекурсии, то это также может быть правильным ответом...
ОБНОВИТЬ:
Если я изменил <c:forEach/>
на <ui:repeat/>
и вместо использования </c:when>
использовал атрибут "rendered", он застрял и дал мне ошибку "Overflow".
Почему <ui:repeat/>
с <ui:include/>
в итоге дает мне ошибку переполнения?
Благодаря @BalusC, я получил информацию для успешного решения из этого источника: c: forEach внутри правлений (например, p: panelgrid) внутри ui: repeat.
Код, который у меня есть, написанный dashboard.xhtml - это только одна часть всего кода. Эта часть находится в двух других таблицах данных. Я не знаю, связаны ли с 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-й главе).
Вместо <c:when test="#{comment.hasChildren}">... </c:when>
использовать <ui:fragment rendered="#{comment.hasChildren}">... </ui:fragment>
и вместо внутреннего <c:forEach/>
используйте другой <ui:repeat/>
. Просмотр в Интернете или stackoverflow вы можете найти хорошие статьи, объясняющие, почему смешивание JSTL с Facelets приводит к проблемам.
- РЕДАКТИРОВАТЬ Вы должны передать свой комментарий в качестве параметра в свой файл include:
<ui:include src="comments.xhtml">
<ui:param name="comment" value="#{comment}" />
</ui:include>