组件(component)是一种用户接口(UI)对象,如一个标签、按钮、树。
页面(page)是一个组件的集合。
桌面(desktop)是一个包含相同URL请求的页面。
4.1、ZUML页面的生命周期
(1) 页面初始化阶段
ZK会运行一个叫做init的处理指示。如果没有定义这样的处理指示,就会跳过这个(初始化阶段)。
对于每个init处理指示,都有一个class属性,在其中会创建一个指定类的失利,并调用她的doInit()方法。<?init class="MyInit"? >指定了MyInit类作为页面的初始化类。这个类的处理依赖于你的应用程序的需求。
另一种传递init处理指示的方式是,制定一个zscript文件。<?init zscript="/my/init.zs"?>,那么会在页面初始化阶段对这个zscript文件进行解析。
当执行页面初始化阶段时,并没有在桌面中添加页面。
(2)组建创件阶段
ZK加载器解析ZUML页面,创建并初始化组件。
a、对于每个元素而言,ZK加载器检查if和unless属性,判断它们是否为true。如果不是,就会忽略这个元素及他的子元素。
b、对于一个集合而言,如果指定了forEach属性,ZK将为集合中每个集合项一次执行以下步骤c~g。
c、ZK加载器根据元素名称或类中指定的use属性,参加一个组件。
d、按照顺序一个个地初始化组件类的成员,并在ZUML页面中指定属性。
e、ZK加载器解析到任意嵌套元素,就重复整个过程。
f、如果组件实现了org.zkoss.zk.ui.ext.AfterConpose接口,加载器将调用afterCompose()方法。
g、创建完所有子元素后,将发送onCreate事件给该组建,这样应用程序就能够接着初始化剩下的元素内容。子组件首先提交onCreate事件。
(3)事件处理阶段
在时间处理阶段中,zk一次调用桌面队列(queue)中每个事件监听器。每次调用监听器都会使用一个独立的线程,因此它能够进行自动悬挂式运行,而不影响其他事件的处理。
在处理过程中,一个事件监听器可能会触发另外的事件。
(4)回填阶段
处理完所有的事件后,ZK将所有的组件会天到一个有规则的HTML页面中,并将该页面发送给浏览器。要回填组件,需要调用redraw()方法。
redraw()方法不会改变组件的任何内容。
4.2 更新页面
ZK异步更新引擎将请求以管道的形式添加到队列中,并未每个桌面创建一个队列。因此,同一个桌面的请求会按顺序进行处理,不同的桌面请求会并发进行处理。
(1)请求处理阶段
ZK异步更新引擎可能会根据请求中的要求来更新相关的内容,这样,这些组件和显示在客户端的内容保持一致。然后,ZK异步更新引擎将相关的事件提交到队列中。
(2)事件处理阶段
这个阶段和加载ZUML页面的时间处理阶段采用同样的方式。他一次处理事件,并且对每个事件的处理使用独立的线程。
(3)回填阶段
处理完所有事件后,ZK传送已更新的组件,生成相应的ZK响应,并将这些响应信息发送会客户端。客户端引擎根据这些响应信息更新浏览器中DOM树。
4.3 组件垃圾回收
ZK的每个组件并没有destroy()或close()方法。只要从页面上卸载了组件,就应该从浏览器中删除了该组件。一个页面一旦卸载了一个组件,如果应用程序没有任何指向它的引用,那么ZK将不再对其负责管理。而组件分配的内存将通过Java虚拟机(JVM)的垃圾收集器进行释放。
4.4 使用组件的属性
4.4.1 组件id,if,unless
组件一般使用的属性是id,它为组件分配一个唯一的标识符。可以在if或unless属性中制定相关语句,来决定是否创建组件,而且也可以使用forEach属性来决定要创建的组件数量。同时,也可以使用use属性将组件赋值给另一个Java类,这样可以替换原来默认的Java类。
if和unless属性定义true或false,可以用来判断是否创建组件。如果为组件指定了这两个属性,那么只有这两个属性均为true时才创建该组件。
4.4.2 组件的forEach属性
组件的forEach属性用来决定创建多少个组件。若为一个集合对象指定了该属性,zk加载器将会为该集合内的每一个条目创建一个组件。
4.4.3 组件use属性
将UI部分代码和控制处理的代码进行分离,可以减轻维护的负担。试图分离常见两种方式:
将控制代码放到一个单独的类中,然后注册事件监听器来调用和公司的方法。
另一种方式是使用use属性指点过一个类来取代默认的组件类。
<window use="MyWindow" />