先簡單介紹一下ZK架構: 是個ajax架構,事件驅動架構,最大優點免去了編寫js這種痛苦的工作,并且像開發桌面程式一樣來開發web應用,簡單明了。(雖然以後可能普遍html5,可是這還是需要一定時間的過渡)。缺點:雖然是台灣的開源架構,可是國内貌似不怎麼火爆,也就是說資源比較少,意味着英語要不錯,且要有專研精神。官方論壇的small talk是不錯的,ZK架構的好資源基本在那裡,中文的參考手冊卻有部分的錯誤(ps,參考手冊的一個錯誤曾讓我抓狂)。還有一個缺點是開源架構普遍存在的一個缺點,就是版本更新了,文檔卻沒有更新。當改動比較大的時候,有時比較難找到對應的文檔。(必須要時刻關注着)。
先說下ZK的原理,在用戶端第一次通路ZK web應用的時候,用戶端浏覽器會download的ZK架構在用戶端的運作部分(ZK用戶端),而ZK用戶端會檢測使用者在用戶端的動作,然後發送對應的ZK request 到服務端,而ZK架構的Au Service (更新服務)會根據ZK request來發送ZK response給ZK用戶端接收,ZK用戶端然後進行處理。
在java web應用開發的時候就會感覺到就像是開發java 桌面程式一樣。對web 界面上的button進行監聽,當發生onClick事件的時候就發送ZK request 到服務端,服務端就自動調用對應的java 處理程式。(這點讓人很happy~讓人覺得前端和背景無差别開發)。
技術上總結:
ZK架構有很多元件,元件有對應的類。
web界面的開發有兩種方式,第一種 完全ZK化,界面使用ZK 提供的前端開發的語言進行開發(不用擔心,ZK前端開發的語言和html非常相似,學習不難),且可以在完全ZK界面上面嵌入html和js以及其他的腳本語言。第二種是将ZK元件嵌入到html頁面上面。(不怎麼喜歡這種,覺得沒啥意義,隻是ZK架構為了多種需求而已)。
在開發的時候主要使用的是第一種方式。
用一個案例進行開發,比許a.zul 可是使其有對應的java處理類。a.zul 在界面中使用 屬性apply 可以指定對應的java處理類A.java。 可是A.java得繼承或實作ZK架構中的類,有幾種方式:
1,a.zul界面使用屬性use ,a.java 繼承Windows類。
a.zul 界面:
Java代碼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5SYlFTOlVjNlZ2MkhzNmZTNxYWYhZmNzITY4YjN2Y2Y58CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
use="org.rjb.com.custom.CustomWin" width="300px">
model="${win.customers}" />
width="200px" onFocus="win.onFocusName()" />
use="org.rjb.com.custom.CustomWin" width="300px">
model="${win.customers}" />
width="200px" onFocus="win.onFocusName()" />
注意: window裡面有一個屬性use, 事件onFocus 的處理【window 的id】.【a.java的處理方法】
a.java
Java代碼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5SYlFTOlVjNlZ2MkhzNmZTNxYWYhZmNzITY4YjN2Y2Y58CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
public class CustomWin extends Window{
DataSource _dr=new DataSource();
public ListModel getCustomers(){
return _dr.getCustomers();
}
//事件處理方法
public void onFocusName(){
final Textbox text=(Textbox) this.getFellow("text");
final Listbox list=(Listbox)this.getFellow("list");
text.setValue("Dear:"+(list.getSelectedItem()==null?"NULL":
list.getSelectedItem().getValue().toString()));
}
}
public class CustomWin extends Window{
DataSource _dr=new DataSource();
public ListModel getCustomers(){
return _dr.getCustomers();
}
//事件處理方法
public void onFocusName(){
final Textbox text=(Textbox) this.getFellow("text");
final Listbox list=(Listbox)this.getFellow("list");
text.setValue("Dear:"+(list.getSelectedItem()==null?"NULL":
list.getSelectedItem().getValue().toString()));
}
}
注意:繼承Window類這種方法,可以通過this.getFellow(“ 元件id”);這種方法來得到對應的元件,且操作它。
第二中方法:
a.zul裡面使用apply屬性
Zul代碼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5SYlFTOlVjNlZ2MkhzNmZTNxYWYhZmNzITY4YjN2Y2Y58CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
apply="org.rjb.com.custom.MyAutoWireComposer" width="300px">
forward="onFocus=onFocusName" />
apply="org.rjb.com.custom.MyAutoWireComposer" width="300px">
forward="onFocus=onFocusName" />
注意:apply屬性使用後,對應元件的forward方法,指定事件onFocus 這裡注意到事件處理必須以on開頭。(至少我開發的時候,曾經因為這個出現了錯誤。)
a.java對于這種方式可以有多種繼承:
早期的: 使用GenericAutoComposer可以自動檢測到元件,不用手動輸入得到元件。但是要指定對應的事件處理的。
Java代碼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5SYlFTOlVjNlZ2MkhzNmZTNxYWYhZmNzITY4YjN2Y2Y58CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
public class MyAutoWireComposer extends GenericAutowireComposer{
private Listbox list;
private Textbox text;
//在界面生成以後的處理
public void doAfterCompose(Component comp)throws Exception{
super.doAfterCompose(comp);
DataSource _dr=new DataSource();
ListModel lm=_dr.getCustomers();
list.setModel(lm);
}
public void onFocusName(){
StringBuffer stf=new StringBuffer("Dear:");
stf.append(list.getSelectedItem()==null?"NULL":list.getSelectedItem().getValue().toString());
System.out.println(stf.toString());
text.setValue(stf.toString());
}
}
public class MyAutoWireComposer extends GenericAutowireComposer{
private Listbox list;
private Textbox text;
//在界面生成以後的處理
public void doAfterCompose(Component comp)throws Exception{
super.doAfterCompose(comp);
DataSource _dr=new DataSource();
ListModel lm=_dr.getCustomers();
list.setModel(lm);
}
public void onFocusName(){
StringBuffer stf=new StringBuffer("Dear:");
stf.append(list.getSelectedItem()==null?"NULL":list.getSelectedItem().getValue().toString());
System.out.println(stf.toString());
text.setValue(stf.toString());
}
}
近期一直使用的方法,
GenericForwardComposer類,可是将事件也自動的綁定,不需要zul界面上指定:
Java代碼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5SYlFTOlVjNlZ2MkhzNmZTNxYWYhZmNzITY4YjN2Y2Y58CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
public class LoginComposer extends GenericForwardComposer{
private Textbox login_name;
//事件監聽方法,注意方法名 且要注意這個元件有這種事件(參考手冊)
public void onClick$loginBtn(Event event){
sessionScope.put("login_name", login_name.getText());
Executions.getCurrent().sendRedirect("index.zul");
}
}
public class LoginComposer extends GenericForwardComposer{
private Textbox login_name;
//事件監聽方法,注意方法名 且要注意這個元件有這種事件(參考手冊)
public void onClick$loginBtn(Event event){
sessionScope.put("login_name", login_name.getText());
Executions.getCurrent().sendRedirect("index.zul");
}
}
以上是ZK總結的一部分,ZK資料的不齊全以及資料和版本之間差異,讓我寸步難行,第一次發文,文章中也許有些錯誤和不對的,歡迎大家來指正。