vflex="1"/>
3.2.页面加载
ZK加载器(ZKloader)加载并解释页面需要经历四个阶段:
页面初始阶段,组件创建阶段,事件处理阶段及响应阶段。
●页面初始阶段:
在这个阶段,ZK处理处理指令,被称为初始化(init)。
如果并没有定义这样的处理指令,此阶段会被跳过。
对于每个init处理指令都有一个class属性,一个指定类的实例(instance)将会被创建,然后它的doInit方法将会被调用。
。
initclass="org.zkoss.zkplus.databind.AnnotateDataBinderInit"root="./bulletinEditWindow"?
>
Init只需要写在zul页面中即可,写法如下,其中class固定指定这个类即可,root属性值要唯一,可根据window的id进行更改,写法为root=”./窗体id”。
初始处理指令的另一种形式是使用zscript属性指定包含脚本代码的文件(如下)。
那么在页面初始阶段这个文件将会被解释
initzscript="/my/init.zs"?
>
●组件创建阶段:
在这个阶段,ZK加载器(ZKloader)解释一个ZUML页面,它创建并初始组件。
◆对于window(继承composer类的)可以通过监听onCreate事件或实现AfterCompose接口(doAfterCompose(Componentcomp))来完成一些特定应用程序的初始化。
AfterCompose在组件创建阶段被调用,而onCreate事件是由事件监听器来处理的(即先调用doAfterCompose方法,后调用onCreate方法)。
@Override
publicvoiddoAfterCompose(Componentcomp)throwsException{
super.doAfterCompose(comp);//比写
Components.wireVariables(comp,bulletinEditBean);//比写
}
如果你是把页面控件的对象都先在bean类里面,则Components.wireVariables的第二个参数是用bean的名称,如果只是写在Composer类中,则第二个参数只要写this即可。
◆对于Ext,组件的创建在初始化类时实现。
publicBaseMoreListExt(){
//1.绑定页面
Executions.createComponents(this.zul,this,null);//比写
//2.页面控件与java属性绑定
Components.wireVariables(this,this);//比写
//3.绑定监听事件
Components.addForwards(this,this,'$');
//4.监听事件
this.addForward();
}
●事件处理阶段:
ZK依次调用每个事件的监听器,这些事件已经为桌面排好队列。
●响应阶段:
在所有的事件都被处理后,ZK将这些组件组成一个规则的HTML页面并将这个页面送到浏览器。
3.3.java类中获取界面中的组件
我们在写js代码时,获取html中的控件通过docoment.getElementById()获取的。
那么在zk中,要怎么获取呢?
有2种方法:
第一种,在java类中定义变量,这个变量的类型和变量名必须和zul页面中的控件类型以及ID一致。
这样在zk就会自己实现java对象与界面元素的绑定。
第二种方法,通过getFellow(id)。
这与js中的docoment.getElementById()是类似的。
3.4.事件监听
3.4.1.zul与java类的事件交互
zul上的页面交互事件需要传递到页面类中,有3种写法。
●在控件中加事件属性。
这也有2种写法,一种是用forward属性,属性值为需要监听的方法名,然后直接在页面类中实现这个方法即可。
注意,方法名都要以on开头,否则监听不到。
还可以像html一样,直接用zk自带的事件类型做为属性,如onClick、onOpen、onClose等。
关闭
●不定义事件属性,即不在zul页面中写forward或onclick等事件,而是直接在页面类中写即可,写法为:
事件名$控件id()。
使用这种写法时,zul页面中一定要为该控件设定id。
publicvoidonClick$dataExportBtn()throwsException{
Gridg=this.getGrid();
Excel.gridToExcel(g);
}
●Java类中监听页面事件。
当页面控件触发事件时,页面类中监听该事件。
这种写法实际上就是swing中事件的写法。
this.self.addEventListener(Events.ON_OPEN,newEventListener(){
@Override
publicvoidonEvent(Eventevent)throwsException{
Detaildetail=(Detail)event.getData();
}
});
实现监听的方法的参数类型可以有2种,一种是用Event,一种是ForwardEvent。
当用Eevent,用event.getData()取传参,如上面的代码。
当用ForwardEvent时,用event.getOrigin().getData()取传参,如:
publicvoidonSubSelectProdInst(ForwardEventevent)throwsException{
finalProdInsttprodInst=(ProdInst)event.getOrigin().getData();
}
假如监听的事件与处理事件的方法名不一样。
可以用addForwad中转。
3.4.2.java类之间的事件传递
我们经常会遇到一段逻辑处理时,需要让某一控件触发事件,这时候需要在页面类中抛出事件,触发该控件。
抛出事件有2种方式,postEvent和sendEvent。
postEvent的使用方法为Events.postEvent(事件名称,目标,参数)。
其中,目标为要触发的控件,当触发的自身时,则目标填为this,当不需要传递参数时,参数填null。
如:
Events.postEvent("onClickTreeItem",tree,item);
sendEvent的用法与postEvent的一样,如:
Events.sendEvent("onStaffPositionSelectEvent",this,staffPosition);
二者存在区别。
区别1:
postEvent将要触发的事件加到目标的接收事件队列中,当前面的事件执行完后,才执行这个事件;sentEvent让这个事件马上触发。
也就是说,postEvent能够控制事件的执行顺序,sentEvent不行。
区别2:
使用postEvent时,源对象抛出事件后,不管目标对象是否接受成功,它的任务就已完成;使用sendEvent时,抛出事件和接受事件在同一个线程中