Как создать составной компонент для столбца данных?

С учетом этого datatable (естественно работает):

<rich:dataTable var="var" value="#{values}">
<rich:column>
  <f:facet name="header">
   HEADER
  </f:facet>
  <h:outputText value="#{var}" />
</rich:column>
</rich:dataTable>

Если я определяю настраиваемый компонент (также хорошо в синтаксисе и в нужном месте под ресурсами/компонентами):

   <?xml version="1.0" encoding="UTF-8"?>
    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:a4j="http://richfaces.org/a4j"
        xmlns:rich="http://richfaces.org/rich"
        xmlns:composite="http://java.sun.com/jsf/composite">

    <!-- INTERFACE -->
    <composite:interface>
        <composite:attribute name="val" />
    </composite:interface>

    <!-- IMPLEMENTATION -->
    <composite:implementation>
        <rich:column>
            <f:facet name="header">
       HEADER
       </f:facet>
       <h:outputText value="#{cc.attrs.val}" />
       </rich:column>
    </composite:implementation>
    </html>

Почему не работает следующее?

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition template="/WEB-INF/templates/default.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:my="http://java.sun.com/jsf/composite/components">
    <ui:define name="content">
        <rich:dataTable var="var" value="#{values}">
                 <my:mycolumn val="#{var}"/>
                </rich:dataTable>
    </ui:define>
</ui:composition>

Вы знаете, как я могу позволить ему работать (я хочу определить свой собственный столбец и сохранить код)? Большое спасибо! Bye

Ответ 1

Элемент <my:mycolumn> должен быть экземпляром UIColumn как дочерний только действительный элемент UIData во время фазы ответа рендеринга. Все остальные типы UIComponent будут игнорироваться, поэтому не отображаются. Компонентный компонент неявно является компонентом UINamingContaner, который не является UIColumn и поэтому игнорируется.

A PrimeFaces <p:dataTable> с компонентом backing, который расширяет UIColumn, также не будет работать из-за неправильного жизненного цикла составного компонента. Столбец должен быть создан во время создания представления, тогда как тело составного компонента создается во время рендеринга представления.

Решением является создание файла тега вместо него, что означает дополнительный файл .taglib.xml, но он работает безупречно.

/WEB-INF/tags/column.xhtml:

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:rich="http://richfaces.org/rich">
    <rich:column>
        <f:facet name="header">HEADER</f:facet>
        <h:outputText value="#{val}" />
    </rich:column>
</ui:composition>

/WEB-INF/my.taglib.xml:

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
    version="2.0">
    <namespace>http://example.com/my</namespace>
    <tag>
        <tag-name>column</tag-name>
        <source>tags/column.xhtml</source>
        <attribute>
            <description>Column value</description>
            <name>val</name>
        </attribute>
    </tag>
</facelet-taglib>

Примечание. Записи <attribute> не являются обязательными, но хороши для целей документации, например, сгенерированные документы и автозаполнение IDE.

/WEB-INF/web.xml:

<context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>

Использование:

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:rich="http://richfaces.org/rich"
    xmlns:my="http://example.com/my">
    <rich:dataTable value="#{values}" var="value">
        <my:column val="#{value}" />
    </rich:dataTable>
</ui:composition>