【问题标题】:How to create a composite component for a datatable column?如何为数据表列创建复合组件?
【发布时间】:2012-07-11 11:57:06
【问题描述】:

鉴于这个数据表(自然工作):

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

你知道我怎样才能让它工作(我想定义我自己的列并保存代码)吗?非常感谢!再见

【问题讨论】:

    标签: jsf datatable richfaces composite-component


    【解决方案1】:

    我遇到了同样的问题(primefaces),我的妥协:从复合中排除列标签

    <rich:dataTable var="var" value="#{values}">
        <rich:column rendered=#{yesOrNo}">
           <my:mycolumn val="#{var}">
           .. with child nodes if you want ...
           </my:mycolumn>
        </rich:column>
    </rich:dataTable>
    

    【讨论】:

    • 这是一个非常奇怪且不合逻辑的答案如果包含实际上不正确的代码。而且您没有排除列而是包含它,很奇怪。
    • OP 的组合包含rich:column 标签本身。这种折衷是有效的,因为 在复合之外(这就是为什么它可以在视图构建期间创建,而复合组件的主体是在视图渲染期间创建的,正如 BalusC 所说)如果复合包含大代码(就我而言),这可能会有所帮助。语法:它使用问题中的变量和结构。
    【解决方案2】:

    &lt;my:mycolumn&gt; 元素必须是 UIColumn 的一个实例,因为这是在呈现响应阶段UIData 组件的唯一有效子级。所有其他 UIComponent 类型将被忽略,因此不会呈现。复合组件隐含地是 UINamingContaner 组件,它不是 UIColumn,因此被忽略。

    带有扩展 UIColumn 的支持组件的 PrimeFaces &lt;p:dataTable&gt; 也将由于复合组件的错误生命周期而无法工作。列必须在视图构建时创建,而复合组件的主体是在视图渲染时创建。

    解决方案是创建一个标记文件,这意味着一个额外的.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>
    

    注意:&lt;attribute&gt; 条目不是强制性的,但非常适合用于文档目的,例如生成的文档和 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>
    

    【讨论】:

    • 非常感谢 BalusC。但是用这种方法你不能用一些&lt;cc:insertChildren/&gt; 来添加孩子,可以吗?有没有办法使用 jsf/composite 标签并说根 UIComponent 必须是 javax.faces.component.UIColumn
    • @Anthony:只需使用&lt;ui:insert&gt;。不,复合材料没有办法,正如已经回答的那样。
    • 这种变通方法似乎是 JSF 规范中的一个巨大疏忽。上述解决方案也适用于我;但是,我将如何模拟具有新定义的方面的 cc:renderFacet?带有名称的 Ui:define/ui:insert 对我有用。但是,有没有办法仍然提供另一个 f:facet 子并在 column.xhtml 中使用一些等效的 cc:renderFacet?
    • 这一切都很好,但是,为什么我需要编写一个“my.tablib.xml”并在 web.xml 中声明它,而这种机制不需要定义复合材料?
    • @MartinHöller 在column.xhtml 的定义中,您可以使用&lt;ui:insert /&gt; 来定义放置子标签的位置。看来您也可以像使用模板一样定义命名插入点。我测试了将&lt;ui:insert name="foo" /&gt; 添加到column.xhtml 中,并使用&lt;my:column&gt;&lt;ui:define name="foo"&gt;hello quasi facet&lt;/ui:define&gt;&lt;/my:column&gt; 从外部引用它——这似乎有效,即使与直接孩子的未命名&lt;ui:insert /&gt; 结合使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多