一份按需加载数据的教程.
这一份ZKGrails程序发布在 http://docs.zkoss.org/wiki/Use_Load-On-Demand_to_Handle_Huge_Data. 本教程工作于ZKGrails 0.7.1或更高版本.
你需要为本教程准备一个Grails程序,输入:
$ grails create-app ondemand
下一步,你需要安装ZKGrails.当输入下面的命令最新的版本将会被自动安装:
$ grails install-plugin zk
你将使用一个域类Employee去演示本插件.简单的使用create-domain-class命令在Grails中创建域类,并紧跟着你的类名:
$ grails create-domain-class employee
接着往Employee中添加两个属性fullname的username类型为string.
class Employee { String fullname String username static constraints = { } }
$ grails create-zul employee
这个命令同时为你创建一个 grails-apps/composers/EmployeeComposer.groovy 文件.
<window apply="${employeeComposer}"><vbox><image src="images/grails_logo.jpg"/></vbox><listbox id="lstEmployee" width="100%" checkmark="true"><listhead sizable="true"><listheader label="ID" sort="auto" /><listheader label="Full Name" sort="auto" /><listheader label="User Name" sort="auto" /></listhead></listbox><paging id="pagEmployee" pageSize="30" /></window>
你可以在这些代码看到两个属性lstEmployee和pagEmployee.并都将注入到GenericForwardComposer的子类GrailsComposer.它们在你的.zul文件中代表listbox和paging容器.
你可能注意到afterCompose闭包.这个闭包将通过doAfterCompose执行,并在Groovy里初始化你的容器.
任何时候点击pagEmployee换页,这个auto-wired事件处理器onPaging_pagEmployee将会执行.注,处理器工作需要的参数只能是ForwardEvent或Event.
我同时使用Groovy的默认参数声明了redraw方法,在afterCompose里调用redraw()就是redraw(0).
同样在redraw方法里,有两个地方使用了ZKGrail要里的动态方法.第一个是listbox#clear,这将移除所有的listitem.第二个是append,它将接受通过ZK Builder构造的容器.
import org.zkoss.zkgrails.* import org.zkoss.zk.ui.event.* class EmployeeComposer extends GrailsComposer { def lstEmployee def pagEmployee def afterCompose = { c -> pagEmployee.totalSize = Employee.count() redraw() } def onPaging_pagEmployee(ForwardEvent fe) { def e = fe.origin redraw(e.activePage) } def redraw(page=0) { def list = Employee.list(offset: page * pagEmployee.pageSize, max: pagEmployee.pageSize) lstEmployee.clear() lstEmployee.append { list.each { e -> listitem(value: e) { listcell(label: e.id) listcell(label: e.fullname) listcell(label: e.username) } } } } }
首先在执行你的程序前,你需要一些展示的测试数据.打开grails-app/conf/BootStrap.groovy,并添加下面的代码到init闭包里.
def init = { servletContext -> 1000.times { i -> new Employee(fullname: "Name $i", username: "user$i").save() } }
上面的代码我执行1,000次循环去创建域类对象Employee.
$ grails run-app
$ grails run-app
到你的浏览器里输入http://localhost:8080/ondemand/employee.zul