Facelet:<ui:insert>不能放在属性值问题</ui:insert>中

时间:2011-04-13 04:56:39

标签: jsf jsf-2 facelets

我目前正在使用JSF 2.0中的facelets进行实验。

我目前有一个案例,其中2个facelets使用公共网格定义, 仅在一些区域有所不同,例如bean名称,列表名称,标题,网格ID。

所以我想到的是:

  1. 为该网格创建模板,在使用它的页面之间可能不同的区域中使用<ui:insert>
  2. 这两个页​​面,使用模板,使用<ui:define>
  3. 提供模板的参数

    这是我的gridTemplate.xhtml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html 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:p="http://primefaces.prime.com.tr/ui"
        xmlns:fn="http://java.sun.com/jsp/jstl/functions">
    
    <h:head>
        <title>#{msgs.title}</title>
    </h:head>
    
    <h:body>
        <ui:composition template="/template/masterlayout.xhtml">
            <p:dataTable id="<ui:insert name='gridId' />" var="rpb"
                value="#{<ui:insert name='bean' />.<ui:insert name='list' />}">
                <f:facet name="header">
                    <h3><ui:insert name='title' /></h3>
                </f:facet>
    
                .....
    
                <f:facet name="footer">
                    #{fn:length(<ui:insert name='bean' />.<ui:insert name='list' />)} records<br />
                </f:facet>
            </p:dataTable>
        </ui:composition>
    </h:body>
    </html>
    

    这是使用网格模板的facelet之一:

    <ui:composition template="gridTemplate.xhtml">
        <ui:define name="gridId">grid</ui:define>
        <ui:define name="bean">myBean</ui:define>
        <ui:define name="list">myList</ui:define>
        <ui:define name="title">my message !</ui:define>
    </ui:composition>
    

    这个实验结束于:

    javax.servlet.ServletException: Error Parsing /gridTemplate.xhtml: Error Traced[line: 17] The value of attribute "id" associated with an element type "null" must not contain the '<' character.
        javax.faces.webapp.FacesServlet.service(FacesServlet.java:325)
    
    root cause
    
    javax.faces.view.facelets.FaceletException: Error Parsing /gridTemplate.xhtml: Error Traced[line: 17] The value of attribute "id" associated with an element type "null" must not contain the '<' character.
        com.sun.faces.facelets.compiler.SAXCompiler.doCompile(SAXCompiler.java:394)
        com.sun.faces.facelets.compiler.SAXCompiler.doCompile(SAXCompiler.java:368)
        com.sun.faces.facelets.compiler.Compiler.compile(Compiler.java:124)
        com.sun.faces.facelets.impl.DefaultFaceletFactory.createFacelet(DefaultFaceletFactory.java:297)
        com.sun.faces.facelets.impl.DefaultFaceletFactory.access$100(DefaultFaceletFactory.java:92)
        com.sun.faces.facelets.impl.DefaultFaceletFactory$1.newInstance(DefaultFaceletFactory.java:162)
        com.sun.faces.facelets.impl.DefaultFaceletFactory$1.newInstance(DefaultFaceletFactory.java:161)
        com.sun.faces.facelets.impl.DefaultFaceletCache$1.newInstance(DefaultFaceletCache.java:83)
        com.sun.faces.facelets.impl.DefaultFaceletCache$1.newInstance(DefaultFaceletCache.java:79)
        com.sun.faces.util.ExpiringConcurrentCache$1.call(ExpiringConcurrentCache.java:99)
        java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        java.util.concurrent.FutureTask.run(FutureTask.java:138)
    

    我认为这种方法不合理,因此应该有更好的解决方案来满足这种需求。

    我是否应该在这种情况下使用JSF Facelet Tag或JSF Composite Tag?

    请分享您的意见..谢谢!

1 个答案:

答案 0 :(得分:6)

您必须制作复合组件而不是模板

<html 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:cc="http://java.sun.com/jsf/composite">

<cc:interface>
    <cc:attribute name="list"/>
    <cc:attribute name="title"/>
</cc:interface>
<cc:implementation>
    <p:dataTable id="#{cc.id}" var="rpb"
            value="#{cc.attrs.list}">
            <f:facet name="header">
                <h3>#{cc.attrs.title}</h3>
            </f:facet>

            .....

            <f:facet name="footer">
                #{fn:length(cc.attrs.list)} records<br />
            </f:facet>
        </p:dataTable>

</cc:implementation>
</html>

此组件必须放在webapp根目录下resources文件夹内的文件夹中。组件的名称将与文件名相同。因此,对于此示例,我们可以调用myComponent文件夹中的组件/resources/components

/resources/components/myComponent.xhtml

然后,在您想要包含组件的任何页面中,您只需要包含组件的命名空间

xmlns:albert="http://java.sun.com/jsf/composite/components"

并渲染你的组件:

<albert:myComponent id="..." title="..." list=#{someBean.someList} />