2009年10月11日 星期日

[Struts2] Other UI Tags

在前兩篇的文章中,我們提到了許多的 UI tags,包含基本的Collection-based,在這裡我將一些比較不屬於前兩種,但是也是有用的 tags 加以介紹,這應該算是 bonus!以下將介紹三種 tags:1) Label tag、2) Hidden tag 與 3) Double Select tag。

1) Label Tag
Label tag 主要是用來顯示某項資料,並且讓顯示的結果與其他的 UI tags 有相同的格式,也就是以同樣的 theme 來顯示,雖然我們可使用 property tag 來幫助我們顯示,不過這樣就無法與其他 UI tags 使用相同的 theme 了!
在使用 Label tag 時,我們只需要設定 name 與 label attributes 就可以簡單的將 data 帶出!不過因為 Label tag 只是顯示資料,所以資料只會被帶出,不會被帶入!以下就是簡單的例子:
<s:label name="user.name" label="Your Name" />

由於 Label tag 的使用是非常簡單的,我們就不再多說了!

2) Hidden Tag
Hidden tag 的使用也很簡單,此 tag 最主要是希望將某些資料被 form 送出但不要讓使用者知道,在某些情況下是很好用的,例如我們希望使用者填寫 form 的時間不要超過 10 分鐘,我們可以使用 Hidden tag 來紀錄時間,當使用者送出該表單時,後端在將目前時間與 Hidden tag 所送來的時間進行判斷。
由於 Hidden tag 使用方式容易,以下就舉一個例子示範:
<s:hidden name="timestamp" />

3) Double Select Tag

Double Select Tag 算是一個很神奇的 UI tag,因為他提供了一種很特別的功能。讓我們想像一個情況,當我們在註冊某個網站時,我們應該常常會遇到要填寫住址,比較好得網站會給我們兩個下拉選單,一個選擇縣市,另一個則是顯示該縣市對應的鄉鎮市區!對於 programmers 來說,要達到這樣的功能,不外乎採用的是 Javascript 的技術,不過是 synchronize 或 asynchronize,我們都要依靠 Javascript 的幫助,但是有時候我們又不擅長撰寫 Javascript,所以 Double Select tag 就因應而生。
Double Select tag 提供了兩個下拉選單,第一個選擇後,第二個選單會根據第一個選單的選擇來產生第二個選單的內容,就如同我在上面所描述的情況一樣!對於 Double Select tag 來說,list, listKey 與 listValue attributes 就相同於 Select tag 的使用,只是 Double Select tag 多了以下的一些 attributes:




























AttributeTypeDescription
doubleNameString儲存第二個下拉選單的選擇值
doubleListCollection-based第二個下拉選單
doubleListKeyString第二個下拉選單所產生 option 的 key
doubleListValueString第二個下拉選單所產生 option 的顯示

除了原先在 Select tag 中我們就使用過得 list, listKey 與 listValue 之外,所有想要設定 Double Select tag 的第二個下拉選單,attributes 的開頭都是以 double 為首。上面中比較重要的是 doubleName attribute,因為他是必填的選項,doubleName attribute 的目的在於儲存使用者選擇第二個下拉選單的內容,就如同 name attribute 是儲存第一個下拉選單的結果一樣。
那我們要如何讓第二個下拉選單可以動態呢?有兩種方法,第一種是將第二個下拉選單,透過 OGNL 方式寫在 double select tag 中:
<s:doubleSelect name="first"
list="beanList"
listKey="beanId" listValue="beanValue"

doubleName="second"
doubleList="%{top.beanId==1?{'1.1','1.2'}:{'2.1','2.2'}}"
/>
這種方式就必須將第二個下拉選單的內容寫死在頁面上,如果我們需要增加不同的內容,就會顯得礙手礙腳!除非內容很單純,也不會有太多的變化,否則我是不太建議使用這樣的方式來作。第二種方式就顯得有彈性了,我們將第二個下拉選單到 Action 中取得,剩下的就交由 Struts2 framework 幫我們用 javascript 來自動切換:
<s:doubleSelect name="first"
list="beanList"
listKey="beanId" listValue="beanValue"

doubleName="second"
doubleList="nextList(top.beanId)"
doubleListKey="nextId"
doubleListValue="nextValue"
/>
這種方式就代表我們的 Action 中有一個 nextList() method,接受 beanId 的資料型態。也就是如果 beanId 是一個 String,則此 method 就會是 nextList(String next)。當然,我們在這裡回傳的第二個下拉選單內容是以一個 List 來包裝一堆的 JavaBean。透過 nextList,我們可以根據不同的 parameter 內容來回應不一樣的下拉選單內容,達到動態的效果。
如果你仔細觀察就會發現,double select 看似有 AJAX 的動態取內容的效果,其實卻不然,當 double select tag 被執行時,framework 會先迭代 list (也就是第一個下拉選單的內容),並且逐一取得所有的第二個下拉選單內容,再將這些內容組織到 javascript 中!也就是如果第一個下拉選單中有 10 個項目,那我們的 nextList() method 就會先被呼叫 10 次!
另外,讓我們回到上面的範例中,你應該有發現 OGNL 中的 top 關鍵字吧!這是用來儲存第一個下拉選單所選到的物件,就如同我們的範例,我們每一個物件都是一個 JavaBean,所以我們就可以用 OGNL 的特性,將 bean 中的 property 傳遞給 nextList() method!

在這裡我介紹了三個很特殊,但不一定常用到的 tags,Struts2 framework 提供了很多種神奇的 tags,讓 programmer 可以很容易的撰寫出複雜的表單畫面,不過關方網站的說明實在是很少,所以要使用這些 tags 的代價就是必須自己先 survey 過!

P.S. 這篇內容原本要在 8/11 完成,沒想要拖了整整 2 個月,中間歷經了當兵,現在又忙於工作,閒暇之餘趕緊完成~希望大家多多指教~