将此文赠送给zk群朋友:易语静人(455938495) --zk高级群 Software③China 25891428
这个特性,我在写博客介绍forward的时候,本来想系统的写一下的,
觉得一般情况下大家都不会考虑这么多,就没写,
我现在粗略的写一下,如有其它疑问,请在本文评论处提出你的问题,下次浏览博客时我会看到
a,zk中的forward,onClick是要在服务器端执行的,我称之为服务端事件,即触发zk预定义的js代码,
该js代码向服务器发送http请求,例如调用服务器端某方法等
b,w:onClick是html里的onClick,即普通的事件,我称之为客户端事件,调用的是你写的js代码,
仅运行于浏览器端, 如果你不主动请求服务器端, zk不会主动向server发送消息
zk中事件可以分为4种,
1,Express事件,即EventListener实现了Express接口的事件
2,EventHandler,所谓EventHandler是你在页面上定义的事件
例如<button onClick="java代码"/>,zk在加载页面解析此处onClick的时候会创建一个Zscript实例
当你点击触发onClick后,会调用page的解析器,page.interpret(zscript.getLanguage(), zscript.getContent(page, _comp), scope);
解析执行onClick里的java代码
3,普通EventListener
4,Component类定义的事件,以on开头的 public void方法 onXXX
zk中组件事件的处理是由EventProcessor事件处理器处理的,组件事件处理顺序如下:
1,Express事件,按照component.addEventListener()添加的顺序调用Express类型EventListener,
2,EventHandler
3,普通EventListener,按照component.addEventListener()添加的顺序调用
4,Component类定义的事件
5,注册到组件所属page上的事件监听器,按照page.addEventListener()添加的顺序调用
以下是org.zkoss.zk.ui.impl.EventProcessor的相关源码
private void process0(Scope scope) throws Exception {
final Page page = getPage();
if (page == null || !page.isAlive()) {
String msg = (page == null ? "No page is available in "+_desktop: "Page "+page+" was destroyed");
if (_desktop.isAlive())
msg += " (but desktop is alive)";
else
msg += " because desktop was destroyed.\n"
+"It is usually caused by invalidating the native session directly. "
+"If it is required, please set Attributes.RENEW_NATIVE_SESSION first.";
log.warning(msg);
}
final ExecInfo execinf;
((ExecutionCtrl)_desktop.getExecution())
.setExecutionInfo(execinf = new ExecInfo(_event));
final String evtnm = _event.getName();
for (Iterator it = _comp.getListenerIterator(evtnm); it.hasNext();) {
//Note: CollectionsX.comodifiableIterator is used so OK to iterate
final EventListener el = (EventListener)it.next();
execinf.update(null, el, null);
if (el instanceof Express) {
el.onEvent(_event);
if (!_event.isPropagatable())
return; //done
}
}
if (page != null && _comp.getDesktop() != null) {
final ZScript zscript = ((ComponentCtrl)_comp).getEventHandler(evtnm);
execinf.update(null, null, zscript);
if (zscript != null) {
page.interpret(
zscript.getLanguage(), zscript.getContent(page, _comp), scope);
if (!_event.isPropagatable())
return; //done
}
}
for (Iterator it = _comp.getListenerIterator(evtnm); it.hasNext();) {
//Note: CollectionsX.comodifiableIterator is used so OK to iterate
final EventListener el = (EventListener)it.next();
execinf.update(null, el, null);
if (!(el instanceof Express)) {
el.onEvent(_event);
if (!_event.isPropagatable())
return; //done
}
}
final Method mtd =
ComponentsCtrl.getEventMethod(_comp.getClass(), evtnm);
if (mtd != null) {
// if (log.finerable()) log.finer("Method for event="+evtnm+" comp="+_comp+" method="+mtd);
execinf.update(mtd, null, null);
if (mtd.getParameterTypes().length == 0)
mtd.invoke(_comp, null);
else
mtd.invoke(_comp, new Object[] {_event});
if (!_event.isPropagatable())
return; //done
}
if (page != null)
for (Iterator it = page.getListenerIterator(evtnm); it.hasNext();) {
//Note: CollectionsX.comodifiableIterator is used so OK to iterate
final EventListener el = (EventListener)it.next();
execinf.update(null, el, null);
el.onEvent(_event);
if (!_event.isPropagatable())
return; //done
}
}