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 является двухэтапным процессом.
Во-первых, во время построения представления исходный код XHTML анализируется и превращается в дерево Java.
UIComponent
экземпляры, представляющие дерево компонентов пользовательского интерфейса JSF, как доступноFacesContext#getViewRoot()
,Затем во время визуализации представления дерево компонентов пользовательского интерфейса 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>
вместо.