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 для динамического генерации столбцов из источника данных.