上一篇
Facelets使用XHTML規範,省卻了一大堆JSP的<f:verbatim />;
更強的性能;
Facelets實現模板(Template)功能,這個可以稱得上是殺手鐧功能.幾乎每個應用都要使用這個功能;
Facelets還可以方便地創建自定義標籤和EL函數.
所以Facelets成為Seam的不二之選.通過上面的講述,我想大家應該了解Seam、JSF與Facelets的關係,故我介紹使用Facelets作為視圖技術的JSF.
基本的XHTML構成
如果大家可以通過上一篇文章可以順利創建Seam工程,可以在WebContent文件夾下看到一些XHTML文件.不過,這些XHTML都並不是獨立的,需要依賴模板頁面.下面讓我們來看一個完整的XHTML:
<?xml version="1.0" encoding="utf-8"?> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> |
這個文件的構成很簡單,與普通的XHTML區別就是引入了「http://java.sun.com/jsf/html」命名空間.這個URI正是JSF常用的組件(Component,在JSF里的稱呼,可以理解為JSP中的標籤)的URI,<h:outputText />就是其中之一.
另外,需要指出的是上述文件並沒有<f:viewRoot />.這個在以JSP作為視圖技術的JSF的頁面中是必需的.JSF的頁面其實在內存中模型就是一棵樹,如下圖所示.理解這點非常重要,所以是必須有根節點.Facelets的FaceletViewHandler會自動創建一個UIViewRoot,如果XHTML中沒有定義的話.
常用的JSF組件
常用的JSF組件可以分為以下幾大類:表單輸入組件、命令組件、輸出組件、數據組件和輔助組件.
除了輔助組件之外,有些屬性是組件共有的:
id屬性,正如我前邊所說「JSF的頁面其實在內存中模型就是一棵樹」,每個組件對應一個節點.每個節點都有一個唯一標識,這就是id屬性.如果你沒有顯式地設置id,JSF會自動幫你生成一個.
rendered屬性,用於指定該組件是否會被輸出到頁面中.
下面我分別對每類組件進行概述.
常用的表單輸入組件
對於表單輸入組件,都會有一個叫value的屬性,通常被設置為一個EL表達式,如#{myBean.myProperty}.在JSF中有一個概念叫雙向綁定,即是在提交表單的時候,JSF通過EL將用戶輸入的值綁定到後台的Managed Bean中;同樣地請求完成後渲染頁面時,JSF亦會通過EL將Managed Bean的值輸出相應的位置.
常用的表單輸入組件有如下 :
h:inputText
h:inputSecret
h:inputTextarea
h:selectBooleanCheckbox
h:selectManyCheckbox
h:selectOneRadio
h:selectOneListbox
h:selectManyListbox
h:selectOneMenu
h:selectManyMenu
在這,我就不一一介紹這些組件的詳細用法,大家可以找一下《Core JavaServer Faces, 2nd Edition》來看一下.
命令組件
JSF的命令組件有<h:commandButton />和<h:commandLink />,分別輸出一個<input type="submit" />和<a />.它們都有兩個屬性action和actionListener,可以綁定到Managed Bean的事件處理方法.例如:
<h:commandButton action="#{myBean.myEvent}" value="Click Me" /> <h:commandButton actionListener="#{myBean.myActionListener}" value="Click Me" /> |
對應的JAVA代碼:
public String myEvent() { return null; } public void myActionListener(ActionEvent event) { } |
常用的輸出組件
這些組件輸出一些常用的HTML元素,如<span />、<a />、<div />和<table />等.其中最常用的應該是<h:outputText />、<h:panelGroup />和<h:panelGrip />.
h:outputText,當id、style和styleClass等屬性不為空時,它會輸出<span />包住value.另外,它還有一個屬性叫escape,用於指示是否需要對值進行HTML編碼,默認為true.對值進行HTML可以從一定程序上防止XSS(Cross Site Scripting,跨站腳本)攻擊.
h:panelGroup,當id、style和styleClass行屬性不為空,且layout不為block時,它輸出<span />.而當上述屬性不為空,且layout為block時,它會輸出<div />.不過,當上述屬性為空時,它將什麼也不輸出.可能有的朋友會問,如果什麼不輸出,那要它何用?這個問題稍後再答.
h:panelGrid,輸出<table />.它的用法有點奇怪,它有屬性叫columns,默認為1.它將包含在其內的JSF組件,分別放到<td />元素輸出.有時,我可能需要將兩個或多個JSF組件放到同一個td中定位,就需要使用到h:panelGroup了.此時,我們不用對<h:panelGroup/>設置任何屬性.這就是上個問題的答案.<h:panelGroup />用於將兩個或多個JSF組件當作一個使用,統一設置它們是否rendered等.例如:
<h:panelGrid columns="2"> <h:outputText value="1" /> <h:outputText value="2" /> <h:panelGroup> <h:outputText value="3" /> <h:outputText value="-" /> <h:outputText value="4" /> </h:panelGroup> <h:outputText value="5" /> </h:panelGrid> |
的輸出如下圖所示:
常用的數據組件
JSF的數據組件有<h:dataTable />,它的使用相對比較簡單,可以將綁定到集合類型.如
<h:dataTable value="#{myBean.myProps}" var="_prop"> <h:column> <f:facet name="header"> <h:outputText value="Header" /> </f:facet> <h:outputText value="#{_prop.myProp}" /> </h:column> </h:dataTable> |
常用的輔助組件
這些組件一般不能單獨使用,而是作為輔助用在不同的組件中,其作用也有所不同.它們的命名空間是xmlns:f="http://java.sun.com/jsf/core",通常以f為前綴,如f:facet、f:param.
小結
本文大概地介紹了一下JSF的組件.雖然JSF默認已經有這麼多的組件,但是對於時下盛行的富客戶端的瀏覽器應用而言還是杯水車薪.因此許多軟體廠商都開發各式各樣的第三方組件,以方便大家構建AJAX應用,如Richfaces、IceFaces等.至於這些組件的詳細用法,大家可以在日後的學習中慢慢熟悉.
[火星人 ] 基於Facelets的JSF已經有977次圍觀