DataTable с динамическими столбцами
Я совершенно новичок в JSF и просто пытаюсь доказать концепцию, чтобы решить, будет ли это полезно для проекта. Мой POC просто состоит из одной страницы с таблицей, содержащей некоторые данные.
Число столбцов (а также количество строк) является динамическим, загружается из базы данных до отображения страницы.
Со следующим я получаю два статических столбца с соответствующим количеством строк, как я ожидал:
<h:dataTable id="data" value="#{viewDataBean.dataRows}" var="row">
<h:column>
<f:facet name="header">
<h:outputText value="Col 1"/>
</f:facet>
<h:outputText value="#{row.values[0].value}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Col 2"/>
</f:facet>
<h:outputText value="#{row.values[1].value}"/>
</h:column>
</h:dataTable>
Что я хотел сделать, это добавить <c:forEach...>
вокруг одного набора тегов <h:column>...</h:column>
, чтобы перебирать количество столбцов, но это не сработало - я пробовал различные комбинации, но я был ожидая чего-то подобного:
<h:dataTable id="data" value="#{viewDataBean.dataRows}" var="row">
<c:forEach items="#{row.values}" var="val">
<h:column>
<f:facet name="header">
<h:outputText value="Col 1"/>
</f:facet>
<h:outputText value="#{val.value}"/>
</h:column>
</c:forEach>
</h:dataTable>
Из Googling я читал различные неопределенные комментарии, такие как "это не способ сделать это", но я не смог найти каких-либо особо убедительных примеров правильного пути. Кто-то упомянул о создании DataTable в базе bean, но единственным примером того, что я мог найти, был http://forums.sun.com/thread.jspa?threadID=577589. Он работал, но чувствовал себя неуклюжим, особенно потому, что некоторые из используемых методов устарели.
В настоящее время маловероятно, что я смогу использовать любые библиотеки, отличные от ядра JSF, но это может измениться, если это абсолютно необходимо. Может ли кто-нибудь пролить свет на правильный способ сделать это? Похоже, это должно быть довольно просто, поэтому я уверен, что я просто пропущу что-то очевидное.
Ответы
Ответ 1
JSTL и JSF не синхронизируются, как вы ожидали от кодирования. Более того, JSTL сначала обрабатывает всю страницу сверху вниз, а затем передает результат в JSF для дальнейшей обработки. #{row}
недоступен в то время, когда JSTL занят, поэтому ваша попытка действительно не будет работать.
Связанная тема действительно упоминает устаревшие методы, но тема также стареет и обсуждает устаревший JSF 1.0/1.1. Если вы исследуете текущие Javadocs упомянутых методов, вы увидите, что - как обычно - упомянуты методы замены. Например, Application#createValueBinding()
упоминает следующее:
Устаревшие. Это было заменено вызовом getExpressionFactory()
, затем ExpressionFactory.createValueExpression(javax.el.ELContext, java.lang.String, java.lang.Class)
.
Вы можете найти некоторые конкретные примеры динамического заполнения datatable таким образом в в этой статье.
В отношении сторонних библиотек компонентов RichFaces имеет компонент rich:columns
, который предназначен именно для этой цели.
Ответ 2
Сторонняя библиотека PrimeFaces имеет компонент p:columns
для динамического генерации столбцов из источника данных.