作者TonyQ (沉默是金。)
看板java
标题[J2EE] 闲聊 zk 2
时间Tue Oct 12 22:52:23 2010
最近去绿岛玩了三天,所以这篇拖的比较晚。(遮脸)
加上写了第一篇後觉得还缺少一只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)
1F:推 wannawanna:有看有推! 10/13 00:17
fix some typo
※ 编辑: TonyQ 来自: 220.133.44.37 (10/13 09:40)
2F:推 GoForward:推!! 转寄到信箱收藏! 10/13 14:36
3F:→ TonyQ:btw , 我的文章都是标明作者出处就可以自己转..:p 10/13 15:02
※ 编辑: TonyQ 来自: 220.133.44.37 (10/13 15:32)
4F:推 gpmm:啊,我知道 T 大您在做什麽了 XD 10/14 00:48
5F:推 gpmm:这个听起来真的超有趣啊 10/14 01:07