[J2EE] 閒聊 zk 2 導論 2

看板java作者 (沉默是金。)時間15年前 (2010/10/12 22:52), 編輯推噓4(402)
留言6則, 4人參與, 最新討論串1/1
最近去綠島玩了三天,所以這篇拖的比較晚。(遮臉) 加上寫了第一篇後覺得還缺少一隻ap做說明,得花點時間作一個, 想想目前還是暫時把這系列設定成一週一篇吧,取材跟時間上或許比較充裕些。 這篇我也先用概念來做些講解,能聊什麼就聊些什麼, 實例操作(真的能讓你們自己拿來跑且有趣)的部份, 拉到再下一篇再談。 :D 其實 zk 先瞭解概念再去接觸或許會有趣些, 因為很多世界觀跟原本的網頁有一點點不太一樣。 ok , 咱們接著聊下去,我會盡量讓它有趣一些的。(笑) 上回講到 zk application 能透過在 zul 中, 用 component tag 組合而成的,接下來我們就要來說說 component 的故事。 ----------------------------------------------------- 一個 component 在 zk 5 主要會由以下幾樣東西構成 1.伺服器端(這裡是 java 的世界) component class event class 2.瀏覽器端(這裡是 javascript+ html+ css 的世界) javascript widget 其中包含 mold -> 一個 javascript 檔案,用來產生 html css -> 就像一般網頁的css檔 widget class-> 一個有特殊規範的 javascript object ----------------------------------------------------- 好,看到這裡別急著睡著, 這些鬼名詞你不需要記得,我要說的其實只有一個, 那就是 zk 的 component 會分成伺服器端(server)跟瀏覽器端(client), 而這就是一切有趣事情的開頭,在這裡你一定還不知道有趣之處, 所以接下來讓我們跟著 component 去探險吧。 :) ----------------------------------------------------- 我們還是先從最基本的視覺呈現開始,假設現在有個 zul 是 index.zul , (忘了什麼是zul的話,看看 #1CgVo5YY (java), 他像是 zk 世界中的 jsp 。:P) 內容是 ----------------------------------------------------- <div> <label value="hello" /> </div> ----------------------------------------------------- 現在有使用者連上了伺服器 http://localhost/index.zul ok , 我們的 web container(這裡先假定是tomcat) , 很開心的照著我們的設定將這個 url 交給我們的 zk servlet , 我們的翻譯機就開始忠實地吃著我們的 zul tag …… 以下僅為假想範例虛擬碼,大概描述一下 zk servlet 做啥事... ----------------------------------------------------- zk 翻譯機(肚子好餓,嚼嚼) div -> new org.zkoss.zul.Div() zk翻譯機 (div有小孩耶,嚼嚼) -> label , value= hello -> new org.zkoss.zul.Label() .setValue("hello") .setParent(div) 翻譯機:哈!吃完了!現在我知道這些東西的結構跟它們的親戚關係了! ----------------------------------------------------- 於是我們就拿到一個 div 中含有一個 label child 的 java 結構, 接著我們把他放到一個叫 desktop 的東西上。:D 在這邊稍微做個說明, zk component 跟 html dom 一樣, 是一個可以有 parent 跟 childrens 的結構, 唯一的限制就是他們都必須至少是 Component 類別。 我們暫時先不要管 desktop 到底是什麼,知道一下有這東西就好, 因為這裡我們產生好這個結構,但是瀏覽器還在等我們回傳 html 給他呀! 我們還是趕緊先餵飽我們的 browser 吧! 再解讀完 zul 結構後,再來溫馨的 servlet 翻譯機, 會把這些結構都趕到真正的網頁原始碼去,並且把他們的定義檔都找出來; 我們先告訴網頁說我們會用到的元素的架構長怎樣, 再透過 json 告訴網頁我們會用到哪些元素跟他們的父子關係, 最後透過瀏覽器組裝成我們要的畫面。 以這個例子來講,我們的 div 將會這樣呈現。 <div id="xxxx" > /* div 的定義檔說要把他的小孩畫在這裡*/ //label 自己說它想要變成底下的html! <span class="z-label" id="yyyy" >hello</span> /* div childrend end */ </div> ----------------------------------------------------- (謎之音)喂!你繞了這麼長一串還講了一堆我看不懂得東西, 你真的以為寫 java 的人都懂 html 跟 serlvet 呀? 呵呵,這裡的確是比較無聊一些,其實在 zk 中你也會比較少看到這部份, 而這裡也的確是寫給懂 html 跟 js 的人看的, 你可以知道 zk 在呈現畫面上跟傳統的html是如何銜接的, 如果你不懂 html + js ,那你也可以瞭解一下, 從 zul 到 html 看起來很像魔術,但是他們其實是一個個嚴謹實作的結果。 ----------------------------------------------------- 其實以上這些東西你都不用管(被打),你要知道的就只是寫 zul , 接著 component 就會知道該怎麼去跟 browser 溝通, 寫 zul 我覺得會比寫 html 來得簡單很多,特別是牽扯到事件, 小小的學習曲線,換一些比較有趣的玩法,不失為一個好嘗試。 ----------------------------------------------------- 其實學 zk 越久,越感嘆於 zk 實在是由每一個小細節堆疊起來的, 就在剛剛其實我們已經談到 zk 中一個很重要而且有趣的點了。 我們到這裡一直都還沒有進入到所謂 ajax , 因為對我們來講,我們只是寫了一些 zul , 做了一些看起來很無聊,我用 html 也能幾秒鐘寫好的東西, 其他的什麼也沒做,對吧?:) 那再來就讓我們來聊些更有趣的事情吧! ----------------------------------------------------- 在 zk 中有一系列跟 input 有關的元素, 其中對我們一般系統最常見的莫過於是 button 囉。 假設我希望有個button , 按下 button 跳個顯示視窗提示訊息, 那我在 zul 該怎麼做? ---就這麼簡單 testbutton.zul <button onClick='alert("hello");' label="hello" /> -- ----------------------------------------------------- 謎之音:咦?alert ? 這是 javascript 嗎? 嘿嘿,那我們來看看這段程式碼會發生什麼事情吧! 首先當使用者連上我們的 http://localhost/testbutton.zul 接著 servlet 一如往常的嚼著 button ,(這次的結構看來比較簡單!) 接著把結構放到desktop ,吐出 html 給 browser 。 咦?這個 component 有 onClick 事件耶, 那我要告訴 browser 要注意,當他被按下時我必須要知道, 不然就太對不起使用者的請求了(事件宣告)。 by desktop 說時遲那時快,一個正在體驗的使用者, 迅雷不及掩耳的就拿起滑鼠點~~~了下去。 首先最先反應到的當然是網頁的元素( html dom element ), 接著事件被 client 的 javascript widget 接到, 可是 widget 他並不知道 server 的 component 到底要幹麼, 只知道 desktop 送它給browser時做了記號, 如果 onClick 事件被觸發,他就需要跟 desktop 說一聲。 於是他拿起電話打給了 server 想找它的 desktop , xmlhttprequest ----> http://localhost/zkau ^ this is so-called ajax 接著接線生接線了,「唯~~很多人在線上啊,你要找哪個desktop啊?」, 哦,你要找的分機是這個啊,那我想我知道你家的 desktop 了。 zkau -> find the active desktop desktop:哦,你要找你在伺服器上的button問說到底要幹麼喔, 你等我一下,我再幫你轉接。 desktop -> find the component -> find event handler onClick 事件處理者:我告訴你~只要呼叫某個好人幫你作一下訊息呈現就好啦~ -> html -> invoke zk alert function 你看吧,其實只是要你跟使用者打個招呼而已,Hello!很簡單吧! ----------------------------------------------------- 你或許會心想: 什麼啊!不過就是 call 一個 jq.alert() 的 javascript 函式, 為什麼要故作玄虛還發個 ajax request 回 server side 啊?? 問的好! 在這個例子中我們的確不一定需要做這樣的溝通, 事實上zk有提供直接綁定 client event ,不用回 server side 的作法。 (稱之為 client side programming , 是zk5 的特色之一. ) 不過在這裡讓我們發揮一下想像力吧! 假設我們今天要做的不是一個單純的alert,而是這樣的東西呢? ----------------------------------------------------- <button label="hello" > <attribute name="onClick"> //myDao 是個假類別,事實上沒有這東西,只是方便說明, //假設這個 dao 操作會去 count 現在資料庫使用者總數, //而且他把資料庫的連線資訊都已經包裝起來了。 // 就像是個 java 應用程式 int users = myDao.countUsers(); alert(users); </attribute> </button> ----------------------------------------------------- oops! 看看我們做了什麼好事, 我們竟然在一個button按下去時就做了一次的資料庫查詢, 對我們來講,竟然完全不用管任何跟 request 有關的東西。 而且還不用換頁,可以拿到即時的反應! ----------------------------------------------------- 回頭想想看在傳統 jsp 我們要怎麼樣寫才能做這件事, 首先我們要先寫好一個 <input type="button" value="hello" id="hello" /> 我假設你夠聰明已經懂得用 jQuery 包裝你的 ajax , (否則你要多寫幾十行就為了一個 request) /*你得先載入 jQuery */ $("#hello").click(function(){ $.post("data.jsp",function(data){ alert(data);//we use alert instead jq.alert in zk }); }); 接著你要寫 data.jsp 或 servlet , 裡面寫上 <% int users = myDao.countUsers(); out.println(users); //讓我偷懶一下寫 scriptlet,意思到就好~~ %> ----------------------------------------------------- 看起來好像跟 zk 差不多簡單,雖然其實我已經偷偷放水很多了, 像是其實 jQuery 還要另外載入,你也必須要另外寫一些東西才能作到 像 zk 這樣比較精緻的 alert 對話框。 而且最麻煩也最重要的是,這樣的 ajax 很難具有泛用性! 我草擬的這個 jsp ajax request 就只能處理 alert 這件事, 如果我今天 ajax 之後想要多個從server傳回來的 label , 那我還得改寫我的程式碼才行。 而且我可能還要增加許多零碎的檔案來處理這些分開的回傳值,(data.jsp) 雖然在某些像是 struts 的framework 你有機會再簡化一些, 但是這些零碎的物件管理,仍然或多或少會造成我們coding上的負擔。 這也是我在 2008 年年底這篇文章提到,ajax的各種挑戰中的一個。 #19CbYPzF (Web_Design) 我曾經致力於把 ajax 跟 javascript 應用盡可能的發揮到一個程度, 這些東西有時候是個好東西,有時候又是個折磨人的小妖精, 我相信曾經有過傳統 ajax 開發經驗的人應該對這些都能夠心有戚戚焉。 ----------------------------------------------------- 嘿嘿,寫到這裡其實這篇已經接近尾聲,我們一次只前進一些, zk 是個非常大而且豐富的世界, 我們不用太著急,一步一腳印繼續向前走就是了。 雖然我很想讓你們跟我一樣玩一玩我所看到的有趣世界。:) it's really interesting. ----------------------------------------------------- 文末我們回頭提到剛剛我們所說得東西,如果按下按鈕後, 要即時增加一個元素在button之後怎麼辦?做得到嗎? ----------------------------------------------------- <button label="hello" > <attribute name="onClick"> int users = 5; // let's just use a fake data now alert(users); //self means the event target , the button. self.getParent().appendChild(new Label("i am new!")); </attribute> </button> ----------------------------------------------------- 瞧,真的很簡單吧,而且 onClick 裡面的東西, 或許有些人會覺得這看起來像是 javascript, (但int users 漏餡了!) 其實這是象徵標準而嚴謹的 java code。:) 我並不是在開玩笑,上述虛線中的東西是真的合法的 zk code, 你可以在 zk 的網站上試試看他(玩玩看嘛,動動手指不會虧本的!:D)。 按照以下的步驟 1.首先打開 zk sandbox http://www.zkoss.org/zksandbox/userguide/ 2.右下角的畫面有個簡單 window,但是那不重要,有個view source按鈕, 如果你有慧根就看得到,點他一下。 3.你會發現顯示畫面變成一個 textarea,嘿嘿! 你現在可以在這個textarea中打入「你自己的」 zk code了, 酷吧! 4.接著把原本的window code清掉,讓textarea變成空白, 把以下紅字的部份複製貼到textarea上。 (你也可以多寫幾個alert或者改一下數字、字串,這很隨性的。) <button label="hello" > <attribute name="onClick"> int users = 5; // let's just use a fake data now alert(users); //self means the event target , the button. self.getParent().appendChild(new Label("i am new!")); </attribute> </button> 5.按下底下的try it,你會發現畫面上出現了一個顯示 hello 的button, 按下去時就會執行我們剛剛所寫得 onClick 定義囉!酷吧! ----------------------------------------------------- 其實我們這一張講得都還是一些非常基本而且小的行為, 但是我相信這些已經足夠開始對 zk 的世界有一點點小小的感覺了, 事實上我們會一章一章從比較小的單位,開始進入到比較大的單位, 我也會陸續介紹一些我們過去在 web project 中, 會需要的東西,在 zk 到底要怎麼實現。 如果有想要看什麼主題,也可以提出討論就是了, 不過基本上前五章我想應該都還是圍繞在zk 主體討論。 我們還有非常多的大大小小的有趣東西還沒開始討論呢! " Magic made of basic. " < 這真是非常的有哲理。^^ TonyQ -- I am a person, and I am always thinking . Thinking in love , Thinking in life , Thinking in why , Thinking in worth. I can't believe any of what , I am just thinking then thinking , but worst of all , most of mine is thinking not actioning... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.71.122.74 ※ 編輯: TonyQ 來自: 111.71.122.74 (10/12 23:01) ※ 編輯: TonyQ 來自: 111.71.122.74 (10/12 23:06)

10/13 00:17, , 1F
有看有推!
10/13 00:17, 1F
fix some typo ※ 編輯: TonyQ 來自: 220.133.44.37 (10/13 09:40)

10/13 14:36, , 2F
推!! 轉寄到信箱收藏!
10/13 14:36, 2F

10/13 15:02, , 3F
btw , 我的文章都是標明作者出處就可以自己轉..:p
10/13 15:02, 3F
※ 編輯: TonyQ 來自: 220.133.44.37 (10/13 15:32)

10/14 00:48, , 4F
啊,我知道 T 大您在做什麼了 XD
10/14 00:48, 4F

10/14 01:07, , 5F
這個聽起來真的超有趣啊
10/14 01:07, 5F

10/14 07:11, , 6F
yep 我們上個月在聊 #1CXFKD32 (Ajax) 時講的就是這東西
10/14 07:11, 6F
文章代碼(AID): #1Cj7OhiS (java)