#jsf #jsf-2 #facelets
#jsf #jsf-2 #facelets
Вопрос:
В настоящее время я экспериментирую с facelets в JSF 2.0.
В настоящее время у меня есть случай, когда общее определение сетки используется двумя facelets, отличается только в некоторых областях, таких как имя компонента, имя списка, заголовок, идентификатор сетки.
Итак, что я имею в виду, это :
- создайте шаблон для этой сетки, используя
<ui:insert>
в областях, которые могут отличаться на разных страницах, которые его используют - эти 2 страницы используют шаблон, предоставляя параметры для шаблона с
<ui:define>
Вот мой 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, который использует шаблон grid :
<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 или составной тег JSF для такого рода случаев?
Пожалуйста, поделитесь своим мнением.. Спасибо!
Ответ №1:
Вы должны создать составной компонент вместо шаблона
<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>
Этот компонент должен быть помещен в папку внутри resources
папки, в корне вашего веб-приложения. Имя компонента будет таким же, как имя файла. Итак, для этого примера давайте вызовем компонент myComponent
внутри /resources/components
папки:
/resources/components/myComponent.xhtml
Затем на любой странице, которую вы хотите включить в компонент, вам просто нужно включить пространство имен вашего компонента
xmlns:albert="http://java.sun.com/jsf/composite/components"
и визуализируйте свой компонент:
<albert:myComponent id="..." title="..." list=#{someBean.someList} />
Комментарии:
1. Здравствуйте, спасибо, что поделились своей мыслью об использовании составного компонента для решения проблемы. Но у меня есть сомнения, не слишком ли сложно создавать составной компонент для сетки, который будет использоваться только на 2 страницах jsf?
2. этот ответ прямо к делу и более точен, чем несколько «руководств» в Интернете по этому вопросу. Поздравляем