H:dataTable всегда отображает одну строку; не будет отображать нулевые строки

Я работаю в устаревшем веб-приложении JSF, и мой элемент h: dataTable вызывает у меня проблемы. Обычно он отображается именно так, как я хочу — заголовок и несколько строк, все с правильными отступами, полями и всем остальным.

H:dataTable всегда отображает одну строку; не будет отображать нулевые строки

Однако, если я попытаюсь отобразить таблицу с нулевыми строками (что является допустимым вариантом использования для меня), JSF по-прежнему отображает одну строку, хотя и пустую от содержимого.

H:dataTable всегда отображает одну строку; не будет отображать нулевые строки

Вот исходный код для этого 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? или у меня что-то не так настроено?

Пожалуйста, порекомендуйте,

-Август

Потому что ваш набор результатов содержит одну пустую запись??? минимальный воспроизводимый пример пожалуйста

Kukeltje 20.02.2019 18:04

Я обновил вопрос, чтобы быть более кратким.

Mathew Alden 20.02.2019 19:26

Кажется воспроизводимым: даже тривиальная таблица данных <h:dataTable><h:column/></h:dataTable> имеет тело со строкой с ячейкой: <table> <tbody> <tr><td></td></tr></tbody> </table>

Selaron 20.02.2019 21:05

Так работает JSF2? Я удивлен, что он вообще отображает <tr>. Может быть, это было сознательное дизайнерское решение? А может это баг?

Mathew Alden 20.02.2019 21:16

Я не могу представить, что это ошибка, если вы не используете самый последний лучший снимок, и это упущение.

Kukeltje 20.02.2019 21:25
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
2
5
543
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Согласно исходному коду 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. Спасибо за разъяснения.

Mathew Alden 20.02.2019 22:06

@AugustZellmer Пожалуйста. Я только что отредактировал ответ, добавив ссылку на фиксацию, подтверждающую, что это преднамеренное поведение.

Selaron 20.02.2019 22:18

И посмотрите, почему информация о версии JSF всегда актуальна для публикации!

Kukeltje 20.02.2019 22:41

Проблемы теперь находятся в github, и если вы добавите 4 к исходному номеру проблемы со старого сайта java.net, вы снова получите проблему: github.com/javaserverfaces/mojarra/issues/1013

Kukeltje 20.02.2019 22:44

@Kukeltje nice1 этого не знал - спасибо :-)

Selaron 21.02.2019 08:05

Я считаю, что даже они сейчас в другом репо. Проверьте ссылки в конце этого выпуска

Kukeltje 21.02.2019 08:33

@Kukeltje Да, модарра работает сейчас в /eclipse-ee4j/Мохарра. Я взволнован тем, что произойдет со всей этой миграцией из Джакарты. Они переименовывают все пакеты? (javax.faces, com.sun, ...) Читал запись в блоге Арджама Таймса в ближайшее время.

Selaron 21.02.2019 08:49

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