Server+client混合模式
除了上面的纯粹的服务器编程方式,我们再介绍一种混合模式。 我们想提高搜索的响应速度,那可以把相应的代码移到客户端。下面我们用搜索功能做一个例子。
修改现有的代码
为了在客户端实现搜索功能,首先我们要加载股票数据到客户端,我们使用一个include组件从服务器端加载data.xml。
Xml代码
Xml代码
Xml代码
客户端编程
为了在客户端实现搜索功能,我们为listbox 创建一个更新方法来生成用户搜索的股票项目。
Xml代码
....
<listbox id="list" rows="10" width="300px">
<attribute w:name="update"><![CDATA[
(function () {
var data;
function loadData(w) {
var xmlDoc = zUtl.parseXML(jq(w).html().replace(/^<!--|-->$/g, '').trim()),
ids = xmlDoc.getElementsByTagName("id"),
labels = xmlDoc.getElementsByTagName("name");
data = [];
jq(ids).each(function (i) {
data.push({id: this.firstChild.nodeValue, label: labels[i].firstChild.nodeValue});
});
}
function createItems (listbox, data) {
if (!data.length) return;
jq(data).each(function () {
listbox.appendChild(new zul.sel.Listitem({label: this.label, uuid: this.id}));
});
}
return function (txt) {
txt = txt || '';
if (!data) loadData(this.$f('data'));
this.clear();
createItems(this, jq.grep(data, function (item) {
return item.label.toLowerCase().indexOf(txt.toLowerCase()) != -1;
}));
this.stripe();
};
})()
]]></attribute>
</listbox>
$f (id), a way to get fellow component. It is the same as getFellow(id), i.e., an alias of getFellow.
http://www.zkoss.org/2005/zk/client is the so-called client namespace that tells ZK engines to generate the code at the client-side instead of server-side.
然后我们为textbox注册一个客户端的onChange监听方法,这个将方法调用listbox的update方法去更新listbox。注意我们要声明一个命名空间(w: ),因为这个监听器是在客户端的。
Xml代码
此外,我们还要在一开始显示所有的股票,这需要调用注册一个bind_方法来实现初始化,这个方法将调用listbox的update方法。
Xml代码
<attribute w:name="bind_">
function (desktop, skipper, after) {
this.$bind_.apply(this, arguments);
var self = this;
after.push(function () {
self.update();
self.firstChild.setSelected(true);
});
}
</attribute>
....
</listbox>
和服务器端交互
最后,还需要和服务器端交换,用户点击一支股票,需要告诉服务器更新历史价格的表格和图表。在listbox上指定onSelect事件,这样一旦用户点击了一个股票,ZK引擎将给服务器发送一个onSelect事件。
Xml代码
接下来,为了在服务器端处理onSelect事件, 我们在服务器端实现一个service,通过它我们可以实现股票历史价格的更新:
Xml代码
....
</listbox>
<include id="content" src="price.zul?id=1"/>
<zscript>
public class MyService implements org.zkoss.zk.au.AuService {
public boolean service(org.zkoss.zk.au.AuRequest request, boolean everError) {
final String cmd = request.getCommand();
if (cmd.equals(Events.ON_SELECT)) {
String uuid = ((List)request.getData().get("items")).get(0);
System.out.println("selected:" + uuid);
content.setSrc("price.zul?id=" + uuid);
return true;
}
return false;
}
}
list.setAuService(new MyService());
</zscript>
总结
在上文中,我们演示了两种不同的实现方式——纯粹的服务器编程和客户端/服务器混合编程——来实现同一个应用。无论使用哪一种,ZK 5 提供了一种新的方式来平衡易于开发和更多的可控性。
译注:最后上传两张IDE中的截图吧,我用的是ZK3.6.2,客户端/服务器端混合编程的方式没有去做。