Board logo

标题: Facelets 非常适合 JSF(4) [打印本页]

作者: look_w    时间: 2018-7-16 12:20     标题: Facelets 非常适合 JSF(4)

要点在进入更高级的示例之前,我想把您的注意力引到几件事上。首先,请注意在清单 5 中,我如何用一种通用方式引用值绑定:
1
<hutputText value="${entity[fieldName]}"/>




第二,当调用这个复合组件时,我把 entity 和 fieldName 作为属性传递,如下所示:
1
<a:column entity="${cd}" fieldName="title" backingBean="${CDManagerBean}"/>




Facelets 使用的 EL 规范允许用圆点(.)表示法或较少使用的映射表示法引用字段。例如,如果像上面那样调用,那么 ${entity[fieldName]} 等价于 CDManager.title。还请注意,我不需要 f:verbatim 标记或辅助的 hutputText。对于您编写的任何 Facelets 页面,都可以这样。Facelets 知道 JSF 组件树,它的唯一目的就是构建这个组件树。这是使用 Facelets 与使用 JSP 和 Tiles 相比的另一个优势。
编写完成之后,就可以在其他许多地方使用 column.xhtml 复合组件。作为一个通用规则:如果正在破坏 DRY 原则,那么请考虑改用复合组件。
创建组件现在通过 column.xhtml 示例已经快速查看了复合组件。下面一步一步地介绍创建复合组件的过程。以下是创建复合组件的步骤:
步骤 1. 创建 Facelets 标记文件标记文件 是符合 facelet_taglib_1_0.dtd 的文件。在概念上它与 JSP 中的 TLD 文件相似。清单 6 是一个示例标记库文件:
清单 6.  标记库文件 —— arcmind.taglib.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
  "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
  "facelet-taglib_1_0.dtd">
<facelet-taglib>
      <namespace>http://www.arc-mind.com/jsf&lt;/namespace>
    <tag>
        <tag-name>field</tag-name>
        <source>field.xhtml</source>
    </tag>
    <tag>
        <tag-name>column</tag-name>
        <source>column.xhtml</source>
    </tag>
    <tag>
        <tag-name>columnCommand</tag-name>
        <source>columnCommand.xhtml</source>
    </tag>
</facelet-taglib>




arcmind.taglib.xml 文件声明了三个标记:field、column(已经看过这个!)和 columnCommand。需要做的只是用 tag-name 指定标记的名称和实现文件的位置。实现文件的名称是相对的。可以在示例 Web 应用程序下的 WEB-INF\facelets\tags 文件中找到所有这些代码,包括 DTD。
请一定注意在上面的标记元素之前声明的 namespace 元素:稍后需要通过它在其他 Facelets 页面中使用这个标记库。
步骤 2. 在 web.xml 中声明标记库有了一个标记库是很好,但是要让它有用,还必须把它的存在告诉 Facelets。在 web.xml 文件中用 facelets.LIBRARIES init 参数做这件事,如下所示:
1
2
3
4
5
6
<context-param>
    <param-name>facelets.LIBRARIES</param-name>
    <param-value>
        /WEB-INF/facelets/tags/arcmind.taglib.xml
    </param-value>
</context-param>




将 facelets.LIBRARIES 以分号分隔的列表形式传递,就可以想定义多少就定义多少标记文件。
步骤 3. 用命名空间导入标记文件创建了标记文件并在 Facelets 标记库中定义了它之后,就可以使用它了。标记文件的使用要求把它声明为 XML 命名空间,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:a="http://www.arc-mind.com/jsf">
...
...
<a:column entity="${cd}" fieldName="title"
  backingBean="${CDManagerBean}"/>
<a:column entity="${cd}" fieldName="artist"
  backingBean="${CDManagerBean}"/>
<a:column entity="${cd}" fieldName="price"
  backingBean="${CDManagerBean}" sort="${false}"/>
<a:columnCommand label="Edit" action="editCD"
              backingBean="${CDManagerBean}"/>




请注意命名空间的定义如下所示:
1
xmlns:a="http://www.arc-mind.com/jsf"




命名空间的值与前面步骤 1 中标记库中声明的命名空间元素一样。
高级技巧上面只介绍了复合组件的基础知识。用我目前为止介绍的内容能够创建可重用组件。在我自己使用 Facelets 时,发现了一些可以让复合组件更有用的小技巧,而且在某些情况下能够解决一些小问题。例如,请考虑来自 cdForm.xhtml 模板的以下代码片段:
清单 7.  cdForm.xhtml 的片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<h:form id="cdForm">
  <h:inputHidden id="cdid" value="#{CDManagerBean.cd.id}" />
  <h:panelGrid id="formGrid" columns="3" rowClasses="row1, row2">
    <!-- Title                                   -->
    <hutputLabel id="titleLabel" for="title" styleClass="label"
                     value="Title" />
    <h:inputText id="title" value="#{CDManagerBean.cd.title}"
                     required="true" />
    <h:message id="titleMessage" for="title" styleClass="errorText"/>
    <!-- Artist                                   -->
    <hutputLabel  id="artistLabel" for="artist" styleClass="label"
                     value="Artist" />
    <h:inputText id="artist" value="#{CDManagerBean.cd.artist}"
                     required="true" />
    <h:message id="titleMessage" for="artist"
                     styleClass="errorText"/>
    <!-- Price                                   -->
    <hutputLabel  id="priceLabel" for="price" styleClass="label" value="rice" />
    <h:inputText id="price" value="#{CDManagerBean.cd.price}"
                     required="true">
        <f:validateDoubleRange minimum="15.0" maximum="100.0" />
    </h:inputText>
    <h:message id="priceMessage" for="price" styleClass="errorText"/>




以上页面在概念上与  类似,但它为 Facelets 和一个字段复合组件留出了空间,可以避免重复代码。基于这个代码,应当可以容易地创建显示字段的复合组件,但是有一个小麻烦。不知道您看到没有?请看表单的 price 字段:它包含一个验证器。
现在,如何把验证器传递给复合组件?




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0