JSF 應用程式的生命週期
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
JSF 生命週期:概述
JSF 程式生命週期的 5 個階段如下(注意每個階段的事件處理):
- 恢復檢視
- 應用請求的值;處理驗證
- 更新模型值;處理事件
- 呼叫程式;處理事件
- 進行響應;處理事件
這 5 個階段顯示了 JSF 通常處理 GUIi 的順序。雖然這個清單列出了每個階段中事件處理的可能執行順序,但是 JSF 的生命週期很難是固定一成不變的。您可以通過忽略某個階段或合併整個生命週期從而對執行順序進行修改。例如,如果一個無效的請求值被拷貝到一個元件中,那麼當前的檢視就會重新顯示,而有些階段就可能不會執行。在這種情況中,您可以執行一個 FacesContext.responseComplete
方法呼叫,將使用者重定向到一個不同的頁面上,然後使用請求分發器(從 FacesContext
中的請求物件中獲得)將其轉發到一個適當的 Web 資源上。另外,您可以呼叫 FacesContext.renderResponse
關鍵是讓生命週期構成您的開發專案,而不完全依賴於生命週期。在需要時,您可以修改生命週期,而不用擔心破壞您的程式。在大部分情況中,您會發現 JSF 的生命週期是值得遵守的,因為它的邏輯非常好。表單必須在任何應用程式邏輯執行之前進行驗證,並且在進行驗證之前,必須對域中的資料進行轉換。遵守生命週期的規定,可以讓您更自由地考慮有關驗證和轉換的問題,而不是請求處理本身的階段。有一點非常重要:其他 Web 框架也都具有類似的生命週期;它們只不過是沒有很好地進行宣傳。
專注
有些使用 JSF 的開發者可能從來都不會編寫一個元件,也不會對框架進行任何擴充套件;而另外一些人則專注於這種任務的開發。儘管 JSF 的生命週期與大部分那其他專案都是相同的,但是根據在專案中的角色您可以採用不同的階段。如果您更專注於通用的應用程式開發,就可能會關注請求處理生命週期的中間階段:
- 應用請求值
- 更新模型值
- 呼叫程式
如果您專注於 JSF 元件的開發,就可能會關注於整個生命週期中的第一個階段和最後一個階段:
- 恢復檢視
- 進行響應
在接下來的幾節中,我們將遍歷 JSF 請求處理生命週期的每個步驟,包括事件處理和驗證。瞭解了每個步驟的基本知識之後,我們將簡要介紹一個示例程式,它可以展示這些步驟如何一起使用。在開始之前,首先來看一下圖 1,這是一個有關 JSF 生命週期的圖。
階段 1:恢復檢視
在 JSF 生命週期的第一個階段 ——恢復檢視 —— 中,會有一個來自 FacesServlet
控制器的請求。控制器會對請求進行考查,並提取出檢視的 ID,這是由 JSPi 頁面的名字來確定的。
JSF 框架控制器使用這個檢視 ID 來為當前的檢視查詢元件。如果這個檢視尚未存在,那麼 JSF 控制器就會建立它。如果這個檢視早已存在,那麼 JSF 控制器就會使用它。這個檢視包含了所有的 GUI 元件。
生命週期的這個階段表示為三個檢視例項:新檢視、原始檢視和後檢視,每個檢視的處理方式都不相同。在 新檢視 的情況中,JSF 會構建 Faces
頁面的檢視,並將事件處理程式和驗證程式繫結到元件上。這個檢視被儲存在一個 FacesContext
物件中。
FacesContext
物件包含了 JSF 用來管理當前會話中當前請求的 GUI 元件狀態所需要的所有狀態資訊。FacesContext
將檢視儲存在自己的 viewRoot
屬性中;viewRoot
包含了當前檢視 ID 的所有 JSF 元件。
在 原始檢視 的情況中(第一次載入的是一個頁面),JSF 會建立一個空檢視。這個空檢視會在使用者事件產生時進行填充。JSF 可以直接從原始檢視過渡到進行響應的階段。
在 後檢視(postback) 的情況中(使用者返回之前訪問過的頁面),包含頁面的檢視早已經存在了,因此只需要進行恢復就可以了。在這種情況中,JSF 就使用現有檢視的狀態資訊來重構狀態。後檢視的下一個階段是應用請求值。
階段 2:應用請求值
應用請求值 階段的目的是讓每個元件檢索自己當前的狀態資訊。這些元件必須首先通過 FacesContext
物件進行檢索或建立(使用其值)。雖然元件值也可以從 cookie 或標頭檔案中進行檢索,但是它們通常是通過請求引數進行檢索的。
如果一個元件的即時事件處理屬性 沒有 設定為 true
,那麼就會對這些值進行轉換。因此,如果 域
被繫結到一個 Integer
屬性上,那麼該值就會被轉換為一個 Integer
型別。如果值的轉換失敗了,那麼就會生成一個錯誤訊息,並在 FacesContext
中進行排隊,在產生響應的階段會顯示其中的訊息,同時還會顯示所有的驗證錯誤。
如果一個元件的即時事件處理屬性 的確 被設定為 true
,那麼這些值就會被轉換為適當的型別,並進行有效性驗證。然後轉換後的值會被儲存到元件中。如果值轉換或值的有效性驗證失敗了,就會生成一個錯誤訊息,並在 FacesContext
中進行排隊,在產生響應的階段會顯示其中的訊息,同時還會顯示所有的驗證錯誤。
處理驗證
生命週期中的第一個事件處理髮生在應用請求值階段之後。在這個階段中,每個元件都有一些值需要根據應用程式的驗證規則進行有效性驗證。這些驗證規則可以是預先進行定義的(JSF 中提供的),也可以由開發者進行定義。使用者所輸入的值會與這些驗證規則進行比較。如果說輸入的值無效,就會向 FacesContext
中新增一個錯誤訊息,並且該元件會被表示為無效的。如果一個元件被表示為無效的,那麼 JSF 就會轉到產生響應的階段,在這個階段中會顯示當前的檢視,以及驗證錯誤訊息。如果沒有有效性驗證錯誤,那麼 JSF 就會轉到更新模型值的階段。
階段 3:更新模型值
JSF 應用程式生命週期中的第三個階段 ——更新模型值 —— 負責更新伺服器端模型的實際值,通常來講,這都是通過更新後臺 bean(稱為管理 bean)的屬性實現的。只有那些與元件值繫結在一起的 bean 屬性才會被更新。注意這個階段發生在有效性驗證之後,因此可以確保拷貝到 bean 屬性的值都是有效的(至少在表單域一級都是有效的;在業務規則一級仍可能無效)。
階段 4:呼叫程式
在生命週期的第四個階段 ——呼叫程式 —— 中,JSF 控制程式會呼叫程式來處理 表單
的提交操作。元件值已經經過了型別轉換和有效性驗證,並被應用到模型物件中了,因此您現在可以使用它們來執行應用程式的業務邏輯了。
在這個階段,您還可以為一個給定的序列或很多可能的序列指定後面的邏輯檢視,這可以通過為一次成功的表單提交定義一個特定的結果並返回這個結果來實現。例如:在成功輸出時,將使用者重定向到下一頁中。要讓這種導航工作能夠起作用,您需要在 faces-config.xml 檔案中建立一個到 成功輸出 的對映作為一條導航規則。一旦導航發生之後,您就轉換到生命週期的最後一個階段了。
階段 5:進行響應
在生命週期的第五個階段 ——進行響應 —— 中,您可以在檢視中顯示當前狀態中的所有元件。
圖 2 是 JSF 生命週期的第五個階段的一個物件狀態圖,包括時間有效性驗證和處理。
範例
現在您已經對 JSF 生命週期的階段有了基本的瞭解,下面我們將向您介紹在一個範例 Web 應用程式中,這些階段是如何協同工作的。除了展示 JSF 生命週期的基本功能之外,這個應用程式還會利用一些通用的 JSF GUI 元件,例如 Radio List, List, Text Field, Label, Panel 等等,這樣您就可以親自體驗一下在 第 1 部分 中曾經簡要討論過的這些元件。
這個示例程式還會展示在 JSF 中使用其他 Javai 技術的兩種方法。它將組合使用 JSF 和 JavaScript 來啟用即時事件處理(在那些對整個表單進行驗證是多餘的情況中),其佈局是由 Struts Tiles 進行管理的。雖然 Struts Tiles 並不是 JSF 的一個必要部分,但是 tiles 通常用來為一個程式中的所有 JSF 頁面提供一致的外觀。
程式設定
這個示例 Web 程式實際上是一個非常簡單的建立、閱讀、更新並刪除(CRUD)一個線上 CD 倉庫中庫存的程式。它包括一個表單,讓使用者可以向系統中輸入新 CD;有一些單選按鈕,讓使用者選擇音樂的分類。當用戶選擇一個分類時,就啟動一些 JavaScript 指令碼將這個表單立即發回伺服器。程式組合採用 JSF 和 JavaScript 技術來處理一個元件,而不是整個頁面,這種技術稱為 即時事件處理。在這種情況中,您可以填充一個子類清單,而不用驗證表單的其他內容。
這個示例程式還包括一個 CD 清單,它將展示如何使用 JSF 的 dataTable
。從這個頁面中,終端使用者可以根據標題或者藝術家對 CD 清單進行排序。
StoreManagerDelegate
類是這個程式的業務代表。它為整個模型呈現了主介面。CD
類是一個數據轉換物件(DTO)。如果這是一個真實的程式,那麼 StoreManagerDelegate
類就會為新增、刪除和編輯 CD 實現所有的業務規則,還會負責使用一個數據訪問物件(DAO)將 CD
儲存到一個永久的儲存介質中。StoreManagerDelegate
和 CD
包含了一些用於這個 MVCi 程式的 模型。
StoreController
類是本例中的主要後臺 bean。StoreController
類是 GUI 世界和模型世界之間的黏合劑。它將自己的很多行為都委託給 StoreManagerDelegate
進行處理。StoreController
是這個 MVC 程式的 控制程式。
StoreController
類展示瞭如何構建一個可排序的 CRUD 清單。它具有以下與 CRUD 相關的方法:editCD
、addNew
、addCD
以及 updateCD
。StoreController
還負責將模型物件呈現給表單。在這種情況中,它使用 cd
屬性將當前的 CD
物件呈現給 CD 表單,該屬性的型別就是 CD
。
開始編碼
開始編寫這個示例程式的最好方法是遍歷它的使用案例:
- 新增 CD
- 編輯現有的 CD
- 根據標題對 CD 進行排序
- 根據藝術家對 CD 進行排序
第三個使用案例和第四個使用案例的程式碼基本上是相同的,因此我將向您展示如何根據標題進行排序,並將第四個使用案例留作練習,請您自行完成。我們很快就會對使用案例進行編碼,但是首先讓我們來了解一下完成後的應用程式的頁面將是什麼樣子。
使用案例 1:新增 CD
在該程式的第一個使用案例中,使用者將新增一個新 CD:切換到 CD 清單頁面上,點選 Add CD 連結(這是在 listing.jsp 檔案中定義的),如清單 1 所示。
|
這個連結被繫結到 CDManagerBean
的 addNew
方法上。這個 addNew
方法在 JSF 生命週期的呼叫程式階段(最後一個階段)被呼叫的。操作被使用 JSF 繫結表示式 #{CDManagerBean.addNew}
繫結到這個方法上。CDManagerBean
是這個程式的儲存控制器的一個別名。CDManagerBean
是這個控制器的邏輯名。控制器類是一個在 faces-config.xml 檔案中定義的管理 bean,如清單 2 所示。
|
準備表單addNew()
方法通過建立一個空 CD 來準備表單,如清單 3 所示。
addNew()
建立一個空 CD 表單
|
addNew()
方法通過建立一個新的 CD 來清空 CD 表單域。這個 CD 表單的域被繫結到 cd
屬性的屬性中。這個方法還會將正在顯示的子類清單置空。
返回成功結果
接下來,addNew()
方法會被呼叫,控制權被重定向到成功對映頁面,即 cdForm.jsp 檔案。cdForm.jsp 檔案是在 faces-config.xml 檔案中定義的,如清單 4 所示。
addNew()
的成功對映
|
清單 4 表明如果使用者從清單切換到 addNew (#{CDManagerBean.addNew})
操作,並且 addNew
操作成功返回,那就會切換到 cdForm.jsp 頁面。
設定 cdForm 和 panelGrid
cdForm.jsp 是包含 CD 表單的表單。其中具有 ID、Title、Artist、Price、Category 和 Subcategory 的域。這些域被放到一個名為 panelGrid
的容器中。JSF 元件,例如 AWTi 元件,具有一些容器和元件。容器 是一個包含其他元件的元件。這是一個 混合設計模式 的例子。panelGrid
有 3 列。每個域都各在一行中,還會有一個標籤和訊息用於顯示該域的錯誤訊息。cdForm
和 panelGrid
是在清單 5 中定義的。
cdForm
和 panelGrid
|
關於程式碼的註釋
每個輸入域都將該域繫結到控制器的 cd
屬性的一個屬性上。例如,標題的輸入文字域被使用下面的 JSF 繫結表示式繫結到 cd
屬性上:value="#{CDManagerBean.cd.title}"
。
您可能會注意到在清單 5 中幾乎沒有什麼 HTMLi 語句。這是由於 panelGrid
會生成大部分的 HMTL 語句。注意實際的外觀是由與 panelGrid
相關的樣式表決定的。屬性 rowClasses="row1, row2"
會為正在修改的行設定 CSSi 類。第一行是白色的,第二行是灰色的。您還可以為列或其他內容指定 CSS 類。JSF panelGrid
元件可以方便地快速設定表單的佈局。如果您希望實現 panelGrid
沒有提供的功能,就不能使用它:不過可以使用 HTML 自己設定元件的佈局。然而,如果您發現自己在很多頁面上都使用了定製的 HTML,那麼就可能會考慮編寫自己的定製元件。這種想法可以讓您儘可能 DRY 地重用 HTML 語句(DRY 是 don't repeat yourself 的縮寫,這個術語來自於 Dave Thomas 的 Pragmatic Programmer 一書)。
關於清單 5 另外需要注意的是控制器有一個 editMode 屬性,由 cdForm.jsp 用於有選擇地顯示 submitAdd
按鈕或 submitUpdate
按鈕;submitAdd
按鈕是在表單不處於編輯模式時顯示的。submitUpdate
按鈕是在表單處於編輯模式時顯示的。這可以簡化為編輯和新增模式使用相同的 JSP。(預設情況下,表單不處於編輯模式。)這種功能是由 cdForm.jsp 中的每個按鈕上的呈現表示式實現的。例如,清單 6 列出了 submitAdd button rendered="#{not CDManagerBean.editMode}"
上的呈現表示式。submitAdd
按鈕被使用表示式 (action="#{CDManagerBean.addCD}"
) 繫結到 addCD
方法上。
addCD()
方法新增一個 CD
|
對域進行有效性驗證
在 addCD
方法被呼叫之前,JSF 必須對 GUI 中的域進行有效性驗證。這實際上非常簡單,因為您還沒有為域關聯任何有效性驗證條件。在應用請求值階段,這些值被從請求引數拷貝到元件值中(這是由元件本身進行的)。現在,價格從一個字串轉換為一個浮點型別。如果使用者為價格輸入的是“abc”,那麼轉換為浮點型別的操作就會失敗,控制權將被重新定向到 cdForm.jsp 頁面上,供終端使用者進行修正。與價格相關的 h:message
將顯示一個轉換錯誤訊息。如果所有的值都可以正常進行型別轉換,並且現在都可以使用了(如果需要的話),那麼您就可以進行有效性驗證的處理了。由於這個示例程式並沒有與元件關聯任何有效性驗證規則(在下一篇文章中我們將介紹這種特性),因此您可以繼續進入更新模型值的階段了。
在更新模型值的階段中,會使用儲存在 GUI 元件中的經過轉換和有效性驗證的值來呼叫 CD 的賦值方法。addCD()
方法是在 呼叫程式 階段中被呼叫的。addCD()
方法使用一個業務代理(store
物件)來執行這個操作。addCD
方法在系統中使用 store
物件來儲存 CD。由於 addCD
方法會返回成功,因此接下來會顯示這個清單,這是在 faces-config.xm 中定義的。在 faces-config.xml 中定義的導航規則如清單 7 所示。
addCD
成功輸出的導航規則
|
使用案例 2:編輯 CD
這個示例程式的第二個使用案例也會在這個清單頁面(listing.jsp)中啟動。除了向您介紹如何編輯 JSF 頁面中的資料之外,這個使用案例還將向您介紹 JSF dataTable
元件。
這個清單頁面使用一個 dataTable
元件來顯示 CD 的清單。dataTable
的值被繫結到控制程式類 StoreController
的 cds
屬性。cds
屬性的定義如清單 8 所示。
cds
屬性
|
cds
屬性是基於從儲存物件 StoreManagerDelegate
返回的 java.util.List
的,這個物件是該程式的業務代理。cdModel
對從 DataModel
中的儲存物件返回的清單進行了封裝。DataModel
是一個用於 dataTable
的模型。
dataTable
的定義如清單 9 所示。
dataTable
定義
|
注意該值被繫結到控制程式的 cds 屬性上。rowClasses
和 headerClass
屬性用來指定 CSS 類,後者用來定義 dataTable
的外觀。正如前面介紹的一樣,JSF 嚴重依賴於 CSS 來定義 GUI 的外觀。如果您並不瞭解 CSS(即您之前都是使用字型標籤和 HTML 表來設定外觀的),就可能會希望在靈活執行 JSF 之前首先來學習一下有關 CSS 的知識。
column 元件Title
、Artist
和 Price
域都是使用 column
元件顯示的,如清單 10 所示(此處只顯示了 Title
域)。
|
column
元件是 dataTable
的一個子元件。column
元件使用一個子元件和一個 facet。facet 是一個有名的子元件;它並不是一個子孫元件。column
元件有一個名為 header 的 facet,它定義了在 header 中顯示的內容。對於本例來說,commandLink
是 column
元件的一個子孫元件。commandLink
在一個連結中顯示了 CD 的標題,該連結被繫結到操作 #{CDManagerBean.editCD}
上。這個操作屬性將 commandLink
繫結到控制程式類的 editCD()
方法上,如清單 11 所示。
editCD
commandLink 的後臺 bean 方法
|
editCD() 方法editCD()
方法是在 JSF 生命週期的呼叫程式階段呼叫的。editCD()
方法準備控制程式以使用編輯模式來顯示 cdForm.jsp 頁面。這是通過檢視當前選定的 CD 來實現的,CD 是通過呼叫 cdModel.getRowData()
方法來選擇的。
注意 JSF DataModel
允許您從比傳統的 Web 應用程式更高的層次上使用資料。您並不需要對請求引數進行檢查:只需要呼叫 cdModel.getRowData()
方法向 DataModel
(cdModel
)查詢已經選擇了哪個 CD。這個更高級別的抽象對 Web 開發進行了相當程度的簡化。
一旦取得當前選擇的 CD 之後,就可以使用業務代理來載入該 CD 的最新拷貝了(store.getCDById()
)。在載入這個 CD 之後,store.getCDById()
會啟用 subCategory
清單(假設這個 CD 已經關聯了一個子目錄),然後將 editMode
屬性設定為 true
。回想一下,editMode
屬性是由 cdForm
用來顯示 Add 或 Update 按鈕。最後,store.getCDById()
方法返回 success。在清單 12 中重要的導航規則可以保證返回成功之後,切換到 cdForm.jsp 頁面,如下所示。
|
updateCD() 方法
CD 表單會載入並顯示 CD 屬性的屬性設定。終端使用者可以根據需要編輯所得到的表單,並在完成時點選 Update 按鈕。Update 按鈕是當用戶處於 Edit 模式時所顯示的惟一一個按鈕,它只會在 editMode
為 true
時顯示,如清單 13 所示。
|
Update 按鈕被繫結到 updateCD()
方法上。在呼叫 update 方法之前,JSF 必須對 GUI 中的域進行有效性驗證。在應用請求值階段,這些值被從請求引數中拷貝到元件值中(這是由元件本身完成的)。現在,價格被從一個字串轉換成了一個浮點型別。由於沒有為元件關聯任何有效性驗證規則,因此如果所有請求的值都已經存在並經過轉換了,就可以轉換到生命週期的下一個步驟了。
更新模型值
在更新模型值階段中,會使用儲存在 GUI 元件中經過型別轉換和有效性驗證的值來呼叫 CD 的賦值函式。updateCD()
方法是在呼叫程式階段被呼叫的。updateCD()
方法如清單 14 所示。
updateCD()
方法
|
updateCD()
方法可以代理業務代理的大部分職責。它將 editMode
設定為 false
(這是預設值),並返回成功。成功輸出將您重定向回清單頁面中,在這個頁面中您可以檢視根據清單 15 中顯示的導航規則新編輯的 CD。
|
使用案例 3:對 CD 進行排序
我們要介紹的最後一個使用案例將向您展示如何對錶進行排序。這個使用案例也是在 CD 清單頁面上啟動的。清單頁允許根據標題和藝術家對 CD 按照升序或降序的順序進行排列。在本例中,我將向您展示如何根據標題進行排序,並將根據藝術家進行排序留作練習。
標題頭排序有一些到控制程式中排序方法的連結。清單 16 顯示了在 listing.jsp 中是如何顯示標題頭的。
清單 16. 對 commandLinks 進行排序
|
panelGroup 元件
注意一下清單 16,連結是在標題列的 header facet 中定義的。facet 只會關聯一個惟一名字的元件;這樣,要在 header facet 中放置一個多連結的元件,您需要使用 panelGroup
。panelGroup
(與 panelGrid
類似)是一個單獨的元件,其中包含了很多子元件。panelGroup
包含兩個連結,如清單 17 所示。
panelGroup
元件連結
|
第一個連結被繫結到控制程式的 sortTitleAsc
方法上,第二個連結被繫結到 sortTitleDec
上。這兩個方法如清單 18 所示。
panelGroup
連結方法
|
這兩個方法都依賴於業務代理返回一個按照正確要求排序後的 java.util.List
。注意這個方法會返回邏輯輸出 asc
和 dec
。這兩個輸出在 faces-config.xml 檔案中都沒有對映。沒有對映的輸出會導致重新載入當前的檢視;這樣,listing.jsp 將會在呼叫這些方法時重新進行載入,清單頁面也會按照正確的順序重新顯示。
這種方法的優點是它依賴於業務代理進行排序。業務代理又可能會依賴於一個 DAOi 物件,而後者又依賴於一個數據庫查詢或 OR 對映查詢,這樣可以對 CD 進行有效的查詢。這種方法通常比具有一個“智慧” GUI 元件的方法更好,後一種方法知道如何對隨機的域物件(CD 就是一個域物件)進行排序,因為排序操作是一個經常發生的操作,嚴格來說,是模型的一部分(即域物件的一部分),而不是檢視的一部分。
正如前面介紹的一樣,對標題進行排序和對藝術家進行排序的程式碼幾乎是相同的。作為一個練習,請自己試圖為第四個使用案例編寫程式碼,對藝術家而不是標題進行排序。
即時事件處理
我們要介紹的最後一個主題是即時事件處理。即時事件處理在您不希望(或需要)對整個頁面進行有效性驗證來處理使用者輸入的情況中非常有用。回想一下,示例程式的 cdForm.jsp 頁面使用單選按鈕來顯示一個目錄和子目錄清單。當終端使用者選擇一個目錄時,cdForm.jsp 頁面就會使用 JavaScript 重新生成表單,這樣就可以顯示子目錄清單了。
這是一個即時事件處理的例子,因為整個表單 沒有 在呼叫事件處理程式之前進行有效性驗證。相反,類清單的事件處理程式會生成子目錄,並強制 JSF 跳過進行響應的階段。元件的事件處理程式通常都是在呼叫程式階段執行的。即時事件元件的事件處理程式是在應用請求值階段執行的,這發生在其餘元件的型別轉換和有效性驗證之前。
清單 19 顯示了在 cdForm.jsp 頁面中再次顯示的目錄清單。
清單 19. cdForm.jsp 中的目錄清單
|
selectOneRadio
目錄域被繫結到 CD
的目錄屬性(value="#{CDManagerBean.cd.category}"
)上。注意這個即時事件處理被激活了(immediate="true"
)。這種設定意味著 Category
元件的事件會在應用值階段(而不是在呼叫程式階段)進行處理(以及型別轉換和有效性驗證)。
JavaScript 功能是在 onclick="submit()"
這一行 —— 即當用戶進行修改時,它應該立即被提交到 Web 程式中進行處理。
事件處理程式方法
在清單中顯示的可用分類是由 f:selectItems
標籤值(value="#{CDManagerBean.categories}"
)確定的。這個元件的事件處理程式的變化是控制程式的 categorySelected()
方法(valueChangeListener="#{CDManagerBean.categorySelected}"
)。事件處理程式如清單 20 所示。
categorySelected
事件處理程式
|
categorySelected()
方法做的第一件事情是允許 subCategoryList
呼叫自己。categorySelected()
方法然後會使用所選擇的分類值來查詢一個 subCategories
清單。subCategories
屬性被繫結到 subcategoryList
值上。接下來,事件處理程式通過呼叫當前 FacesContext
上的 renderResponse()
方法強制 JSF 轉到進行響應階段。然後,GUI(cdForm.jsp)為當前顯示的目錄重新顯示可用的子目錄。
將元件繫結到控制程式上subCategoryList
元件是從 GUI 上繫結的。正如您可以將值繫結到元件上一樣,您也可以將這些元件繫結到一個控制程式上。子目錄是在 cdForm.jsp 頁面中定義的,如清單 21 所示。
|
binding
屬性允許您將 GUI 的元件繫結到後端的 bean(控制程式)上。這樣,上面的元件就會被繫結到 CDManagerBean.subCategoryList
上,這是在清單 22 中定義的控制程式中的一個屬性。
subCategoryList
屬性
|
即時事件處理只使用了很少的一點 JavaScript 功能(onclick="submit()"
命令),這種靈活的 JSF 生命週期的便利可以讓您處理在一個元件中輸入的資訊,而不用對整個頁面進行有效性驗證。在這個例子中,我們已經介紹了 Category
元件的即時處理是如何讓您可以顯示子目錄,而不用重新載入頁面的。
結束語
在本文中我們使用了一個範例和三個使用案例來介紹 JSF 請求處理的生命週期,並展示了其元件模型的一些必備特性。我們還介紹瞭如何組合使用 JSF 和 Struts Tiles,在 JSF 頁面之間實現更加統一的佈局,如何使用 DataModel
,以及如何組合使用 JSF 和 JavaScript 進行即時事件的處理。