Я работаю в устаревшем веб-приложении JSF, и мой элемент h: dataTable вызывает у меня проблемы. Обычно он отображается именно так, как я хочу — заголовок и несколько строк, все с правильными отступами, полями и всем остальным.
Однако, если я попытаюсь отобразить таблицу с нулевыми строками (что является допустимым вариантом использования для меня), JSF по-прежнему отображает одну строку, хотя и пустую от содержимого.
Вот исходный код для этого h:dataTable:
<h:dataTable styleClass = "table" value = "#{backingBean.emptyList}" var = "result">
<h:column>
<f:facet name = "header">First Column</f:facet>
<h:outputText value = "#{result}"/>
</h:column>
<h:column>
<f:facet name = "header">Second Column</f:facet>
<h:outputText value = "#{result}"/>
</h:column>
<h:column>
<f:facet name = "header">Third Column</f:facet>
<h:outputText value = "#{result}"/>
</h:column>
</h:dataTable>
Вот что рендерит браузер:
<table class = "table">
<thead>
<tr>
<th scope = "col">First Column</th>
<th scope = "col">Second Column</th>
<th scope = "col">Third Column</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
Вот методы вспомогательного компонента, которые дают мне список результатов:
public List<String> getEmptyList() { // incorrectly renders 1 empty row
return Collections.emptyList();
}
public List<String> getThreeRows() { // correctly renders 3 rows
return Arrays.asList(new String[] {"row1", "row2", "row3"});
}
Почему JSF отображает эту пустую строку? Я ожидал, что <tbody>
будет просто пустым. Это правильное поведение для JSF? или у меня что-то не так настроено?
Пожалуйста, порекомендуйте,
-Август
Я обновил вопрос, чтобы быть более кратким.
Кажется воспроизводимым: даже тривиальная таблица данных <h:dataTable><h:column/></h:dataTable>
имеет тело со строкой с ячейкой: <table> <tbody> <tr><td></td></tr></tbody> </table>
Так работает JSF2? Я удивлен, что он вообще отображает <tr>. Может быть, это было сознательное дизайнерское решение? А может это баг?
Я не могу представить, что это ошибка, если вы не используете самый последний лучший снимок, и это упущение.
Согласно исходному коду Mojarra 2.3.8, это поощряемое поведение, за которое отвечает TableRenderer
(как следует из его названия) и явно делает это:
com.sun.faces.renderkit.html_basic.TableRenderer.encodeChildren(FacesContext, UIComponent)
:
if (!renderedRow) {
// if no row with data has been rendered, render that empty row in question:
this.renderEmptyTableRow(writer, data);
}
Ваши варианты включают в себя:
1) Добавьте визуализированный атрибут в свой dataTable:
<h:dataTable value = "#{backingBean.entityList}"
rendered = "#{not empty backingBean.entityList}" ...>
...
</h:dataTable>
<h:outputText rendered = "#{empty backingBean.entityList}"
value = "No data to display, sooo sorry :-("/>
2) Переопределите TableRenderer
, чтобы работа лучше соответствовала вашим потребностям:
package my;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
import javax.faces.context.FacesContext;
import com.sun.faces.renderkit.html_basic.TableRenderer;
public class CustomTableRenderer extends TableRenderer {
@Override
public void encodeChildren(final FacesContext context, final UIComponent component) throws IOException {
final UIData data = (UIData) component;
final int rowCount = data.getRowCount();
if (rowCount > 0) {
super.encodeChildren(context, component);
} else {
// do what super.encodeChildren does, but your way ...
}
}
}
К сожалению, вы не можете просто переопределить com.sun.faces.renderkit.html_basic.TableRenderer.renderEmptyTableRow(ResponseWriter, UIComponent)
и заставить его ничего не делать, потому что это private
.
В faces-config.xml
зарегистрируйте свой собственный рендерер:
<render-kit>
<renderer>
<component-family>javax.faces.Data</component-family>
<renderer-type>javax.faces.Table</renderer-type>
<renderer-class>my.CustomTableRenderer</renderer-class>
</renderer>
</render-kit>
Обновлено: рассматриваемое поведение было введено в коммите, исправляя выпуск №1009 с комментарием:
Fix for issue 1009: Rendered h:dataTable/h:panelGrid without rows/content do not validate against XHTML 1.0 Transitional (and html4)
git-svn-id: https://svn.java.net/svn/mojarra~svn/trunk@7669 761efcf2-d34d-6b61-9145-99dcacc3edf1
Жаль, что я больше не мог найти эту проблему, но @Kukeltje сделал!
Эй, спасибо! Пока Sun намеренно решил отобразить пустую строку, думаю, я не буду ее менять. Я просто боялся, что испортил свой xhtml. Спасибо за разъяснения.
@AugustZellmer Пожалуйста. Я только что отредактировал ответ, добавив ссылку на фиксацию, подтверждающую, что это преднамеренное поведение.
И посмотрите, почему информация о версии JSF всегда актуальна для публикации!
Проблемы теперь находятся в github, и если вы добавите 4 к исходному номеру проблемы со старого сайта java.net, вы снова получите проблему: github.com/javaserverfaces/mojarra/issues/1013
@Kukeltje nice1 этого не знал - спасибо :-)
Я считаю, что даже они сейчас в другом репо. Проверьте ссылки в конце этого выпуска
@Kukeltje Да, модарра работает сейчас в /eclipse-ee4j/Мохарра. Я взволнован тем, что произойдет со всей этой миграцией из Джакарты. Они переименовывают все пакеты? (javax.faces, com.sun, ...) Читал запись в блоге Арджама Таймса в ближайшее время.
Потому что ваш набор результатов содержит одну пустую запись??? минимальный воспроизводимый пример пожалуйста