c:forEach внутри простых лиц (например, p:panelgrid) внутри пользовательского интерфейса: повтор

Я должен динамически составить список таблиц. Каждый из них имеет переменное количество столбцов (с фиксированными строками).

Для этого я сначала положил <p:panelGrid> внутри <ui:repeat>Таким образом, я правильно составил список таблиц.

Затем, чтобы динамически создать столбцы, я попытался поставить оба <ui:repeat> или <c:forEach> внутри <p:panelGrid>, В результате я не получаю строк.

Я написал минимальный пример здесь. В зернах testBackingBeanЯ определил (и инициализировал) переменную ArrayList<ArrayList<String>> tables, Это xhtml, который не дает ожидаемых результатов:

<ui:repeat var="table" value="#{testBackingBean.tables}">
    <p:panelGrid>
        <f:facet name="header">
            <p:row>
                <p:column >header of #{table}</p:column>
            </p:row>
        </f:facet>
        <p:row>
            <c:forEach var="row" items="${table}">
                <p:column>#{row}</p:column>
            </c:forEach>
        </p:row>
    </p:panelGrid>
</ui:repeat>

Примечательно, что заголовок-строка правильно конвертируется #{table} в строку. Проблема в том, что я не вижу строк данных.

Кроме того, если я использую <table> вместо <p:panelGrid> все работает как положено.

Кроме того, я пробовал разные перестановки <c:forEach> а также <ui:repeat> без успеха.

Итак, как я могу динамически создавать больше таблиц (используя простые лица) и устанавливать динамическое число столбцов?

Спасибо!

РЕДАКТИРОВАТЬ: я хотел бы использовать два <c:forEach>, но даже с одним <c:forEach> Я получаю пустой результат. На самом деле, если я попробую следующий xhtml:

<c:forEach  items="${testBackingBean.tables}" var="tabella">
    current element: #{tabella}
</c:forEach>

тогда я получаю пустой результат. (Я знаю, это другой вопрос)

1 ответ

Решение

Переход от исходного кода XHTML к сгенерированному выводу HTML является двухэтапным процессом.

  1. Во-первых, во время построения представления исходный код XHTML анализируется и превращается в дерево Java. UIComponent экземпляры, представляющие дерево компонентов пользовательского интерфейса JSF, как доступно FacesContext#getViewRoot(),

  2. Затем во время визуализации представления дерево компонентов пользовательского интерфейса JSF создает вывод HTML и записывает его в ответ HTTP, начиная с UIViewRoot#encodeAll() метод.

Taghandlers, как и все JSTL <c:xxx> теги, несколько JSF <f:xxx> теги и только несколько Facelets <ui:xxx> теги запускаются во время просмотра. Компоненты интерфейса, как и все JSF <h:xxx> теги, несколько Facelets <ui:xxx> теги и только несколько JSF <f:xxx> Теги выполняются во время просмотра.

<c:forEach> это тег-обработчик и <ui:repeat> является компонентом пользовательского интерфейса.

Другими словами, компоненты пользовательского интерфейса, которые объявлены внутри <c:forEach> воссозданы несколько раз в дереве компонентов JSF на основе <c:forEach items> во время создания представления, которые, в свою очередь, индивидуально генерируют каждый свой собственный вывод HTML во время отображения представления. Компоненты пользовательского интерфейса, которые объявлены внутри <ui:repeat> создаются только один раз в дереве компонентов JSF во время построения представления, которые, в свою очередь, многократно используются на основе <ui:repeat value> производить вывод HTML во время представления рендеринга.

Ваша конкретная проблема вызвана тем, что <ui:repeat var="table"> доступно только во время визуализации представления, но не во время построения представления. <c:forEach> в основном извлекает #{null} в качестве значения, когда он собирается работать во время сборки представления.

Вы можете решить эту проблему, заменив внешний <ui:repeat> от <c:forEach>, Хотя мне интересно, если бы вы не могли лучше использовать <ui:repeat><p:dataTable><p:columns> вместо.

Смотрите также:

Другие вопросы по тегам