JSF - c: forEach не работает с рекурсивным методом

1

Я не буду вставлять свои бобы и классы моделей, потому что все в порядке с кодом. Проблема в том, что первый цикл (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>

Визуальная проблема: Изображение 174551

ИЛИ

Если у кого-то есть лучшее представление о методе рекурсии, то это также может быть правильным ответом...



ОБНОВИТЬ:

Если я изменил <c:forEach/> на <ui:repeat/> и вместо использования </c:when> использовал атрибут "rendered", он застрял и дал мне ошибку "Overflow".

Почему <ui:repeat/> с <ui:include/> в итоге дает мне ошибку переполнения?

  • 1
    @BalusC уже что-то ответил об этом, посмотрите! stackoverflow.com/questions/21697024/...
  • 1
    Это было действительно сложно. Это руководство по Вашей ссылке помогло мне, но не совсем так, как оно было там написано. Но, по крайней мере, это дало мне 100% объяснение, почему эта проблема появилась, как можно было ее решить. Благодарю вас.
Теги:
loops
recursion
jsf
primefaces

2 ответа

0
Лучший ответ

Благодаря @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-й главе).

-1

Вместо <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>
  • 0
    Я уже пробовал это раньше .. Вызывает эту ошибку: "/comments.xhtml @ 9,49 value =" # {comment} «Не удалось разрешить переменную [переполнение]: комментарий».
  • 0
    @TomsBugna см. Мое редактирование
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню