How to create a composite component for a datatable column?

巧了我就是萌 提交于 2019-11-26 09:37:55

问题


Given this datatable (naturally working):

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

If I define a custom component (also ok in the syntax and at the right place under resources/components):

   <?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>

Why does the following does not work?

<?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>

Do you know how could I let it work (I want to define my own column and save code)? Thanks a lot! Bye


回答1:


The <my:mycolumn> element must be an instance of UIColumn as that's the only valid child of a UIData component during the render response phase. All other UIComponent types will be ignored, thus not rendered. A composite component is implicitly a UINamingContaner component, which isn't a UIColumn and therefore ignored.

A PrimeFaces <p:dataTable> with a backing component that extends UIColumn also won't work due to the wrong lifecycle of a composite component. The column has to be created during the view build time, while the composite component's body is created during view render time.

The solution is to create a tag file instead, which means an extra .taglib.xml file, yet it works flawlessly.

/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>

Note: The <attribute> entries are not mandatory, but are nice for documentation purposes, such as generated docs and IDE autocomplete.

/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>

Usage:

<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>


来源:https://stackoverflow.com/questions/11439886/how-to-create-a-composite-component-for-a-datatable-column

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!