Пользовательский тег Facelets с несколькими дочерними компонентами в h:panelGrid

Я написал собственный тег, расширяющий UIComponentBase,
Добавляет несколько дочерних компонентов (UIComponent) в течение encodeBegin метод.

В целях верстки я хотел бы вложить эти дочерние компоненты в h:panelGrid,
но тег мешает здесь.

ExampleTag.java

private ExampleTag extends UIComponentBase {

    public void encodeBegin(FacesContext context) throws IOException {
        getChildren().add(new HtmlLabel());
        getChildren().add(new HtmlOutputText();
    }
}

ExampleOutput.xhtml

<html>
    <h:panelGrid columns="2">
       <foo:exampleTag />
       <foo:exampleTag />
    </h:panelGrid>
</html>

Сгенерированный вывод будет иметь HtmlLabel а также HtmlOutput компоненты в той же ячейке,
но я бы хотел, чтобы они были в одном ряду, то есть в двух ячейках.

1 ответ

Решение
  1. h:panelGrid контролирует только макет своих собственных дочерних элементов (а не дочерних элементов его дочерних элементов)
  2. каждый <foo:exampleTag /> создает один составной элемент управления (со своими дочерними элементами)

Если вы хотите добавить несколько элементов управления в h:panelGrid, используйте один из других шаблонных механизмов.

Например, это h:panelGrid использует ui:include:

    <h:panelGrid columns="2">
      <ui:include src="gridme.xhtml">
        <ui:param name="foo" value="Hello,"/>
        <ui:param name="bar" value="World!"/>
      </ui:include>
      <ui:include src="gridme.xhtml">
        <ui:param name="foo" value="Hello,"/>
        <ui:param name="bar" value="Nurse!"/>
      </ui:include>
    </h:panelGrid>

Включенный файл композиции:

<!-- gridme.xhtml -->
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html">
  <h:outputText value="#{foo}" />
  <h:outputText value="#{bar}" />
</ui:composition>

Подмножество представления представления:

<table>
<tbody>
<tr>
<td>Hello,</td>
<td>World!</td>
</tr>
<tr>
<td>Hello,</td>
<td>Nurse!</td>
</tr>
</tbody>
</table>

Будьте осторожны с приведенной выше реализацией - вы не можете явно установить идентификаторы для чего-либо в gridme.xhtml так как нет композитного контроля и, следовательно, нет NamespaceContainer обеспечить детям уникальное пространство имен.


Компонент не является тегом.

public void encodeBegin(FacesContext context) throws IOException {
  getChildren().add(new HtmlLabel());
  getChildren().add(new HtmlOutputText();
}

Это не приемлемый способ создания составного элемента управления. Если вы сделаете это, новые элементы управления будут добавлены к компоненту каждый раз, когда он отображается. Вы также не должны делать это в конструкторе; это тоже приведет к проблемам. Нет хорошего способа добавить дочерние элементы управления в элемент управления; это должно быть сделано внешне с помощью представления (см. выше) или тега.

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