`
yanhua
  • 浏览: 88771 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

ZK5.0和客户端+服务器端相结合的编程方式

阅读更多

译注:我对JSF比较熟悉,最近想研究一些其它的事件驱动的基于组件的WEB层框架,继Wicket和GWT之后,我开始仔细学习了一下ZK,虽然之前说的那几种框架也各有很多的优点,但ZK还是给了我很强的冲击。肤浅的总结一下:

  • 丰富漂亮的组件库。这一点我觉得比JSF和Wicket要强。JSF虽然有很多三方组件库,但是各自为政,虽然都是基于规范的,但大多做了自己的扩展,很难一起使用,比如要想把IceFaces和RichFaces一起用可能就不太现实。致命的是这些三方组件库虽然多但很少有精品,ADF算一个,但必须和Oracle其它部分结合起来才能尽显威力,而且Oracle的产品都是很贵的商业产品。GWT有GXT和SmartGWT到是都很好。
  • 不用编写客户端脚本。这一点其实其他几个框架也都能不同程度的做到,GWT做的最好,但他是client-generate的,这样GWT和服务器的结合相对其它几个server-generate的框架来说比较难一些。JSF和Wicket感觉没有ZK做的透明。就像这篇文章中说的ZK从5.0开始也支持客户端的编程模型了,在某些场合下也是一种不错的选择。而且ZK在UI中可以直接使用服务器脚本,对于一些小项目或原型项目基本可以不写Controller,开发速度可以提升不少。
  • 很棒的可视化开发工具。可以看一下Visual RIA Builder - How to Build a CRUD Application wtih ZK Studio 这个视频。我觉的这得益于ZUL这种界面语言。比如JSF使用jsp或facelets做UI语言,好处是你可以使用任何的html、css和javascript,提供了极大的灵活性,但是这种灵活性都开发一个可视化的IDE来说就是一个很大的难题。而ZUL中各种元素标签的种类和使用方式那是很明确的,这样可以大大简化可视化工具的开发。至于表现的灵活性ZK通过提供大量的组件尤其是布局来解决。
  • ZK的社区比较活跃,不断的在开发和改进,文档和教材以及示例都很丰富。

我现在还在学习,上面只是粗浅的认识,下面是关于ZK5的一篇文章,我照着文章几分钟就做出了一个还挺漂亮的示例,现在把它翻译一下。

原文参见:ZK 5.0 and Client+Server Fusion

 

 

简介

 

从ZK 5开始,开发者不仅能(继续)享受使用服务器为中心的便利开发方式,而且还能使用客户端编程进行全面的控制。二者可以按需选择。这篇文章中将为您分别演示使用服务器为中心的模式和客户端/服务器混合模式来编写一个真实的应用。

 

应用: ZK Finance(ZK 财经)

ZK finance 是一个真实的应用,用户可以查找一个股票的历史价格,并通过一个表格和图表来显示结果。下面是一个界面图,在左面板上有一个搜索框,右边是显示结果的表格和图表。300

 

纯粹的服务器处理方式

首先我们使用服务器端编程来实现这个应用,我们使用MVC (Model-View-Controller) 模式。

 

模型

这里有两个对象——股票和价格。它们是一对多的关系,一支股票有多个历史价格。

Stock.java

public class Stock {


	private int _id;


	private String _name;


	private List _priceItems = new ArrayList();


....


getter and setter methods


}
 

Price.java

public class Price {


	private String _date;


	private double _open;


	private double _high;


	private double _low;


	private double _close;


	private int _volumn;


....


getter and setter methods


}
 

然后我们创建一个DAO对象来负责提供股票数据,StockDAO.java

public class StockDAO {


private List stocks = new LinkedList();


public Stock getStock(int id) {}


public List findAll() {}


 


}
 

 

View

提供一个搜索功能在listbox中显示搜索的结果

index.zul

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>


<borderlayout id="main" apply="StockController">


	<west title="ZK Finance" size="250px" flex="true"


		splittable="true" minsize="210" maxsize="500" collapsible="true">


		<panel>


			<toolbar>


				<label value="Search:" />


				<textbox id="searchBox" ctrlKeys="#down#up"


					focus="true" sclass="demo-search-inp" />


			</toolbar>


			<panelchildren>


				<listbox id="itemList" model="@{main$composer.stocks}"


					fixedLayout="true" vflex="true">											


					<listitem self="@{each='stock'}" value="@{stock}">


						<listcell label="@{stock.name}" />


					</listitem>


				</listbox>


			</panelchildren>


		</panel>


	</west>


	<center>


		<include id="detail"/>


	</center>


</borderlayout>
 

我们使用一个数据表格和图表来显示价格

price.zul

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>


<window id="main2" apply="PriceController">


	<grid id="history" model="@{main2$PriceController.prices}" >


		<columns menupopup="auto">


			<column label="Date" />


			<column label="Open" />


			<column label="High" />


			<column label="Low" />


			<column label="Close" />


			<column label="Volumn" />


		</columns>


		<rows>


			<row self="@{each='price'}">


				<label value="@{price.date}"/>


				<label value="@{price.open}"/>


				<label value="@{price.high}"/>


				<label value="@{price.low}"/>


				<label value="@{price.close}"/>


				<label value="@{price.volumn}"/>


			</row>


		</rows>


	</grid>


 


	<chart id="line" width="500" height="250" type="line"


		fgAlpha="128" model="@{main2$PriceController.cateModel}"/>


</window>
 

 

Controller

 

搜索功能

在StockController.java中我们给TextBox注册一个onChanging事件的监听器,当用户输入时我们搜索股票并把结果显示在ListBox中

StockController.java

public class StockController extends GenericForwardComposer {	


	Textbox searchBox;


	Listbox itemList;


	Include detail;


	StockDAO dao = new StockDAO();


	private static String DETAIL_URL = "price.zul";


 


	public void onCreate$main(){		


		itemList.setSelectedIndex(0);		


		Events.postEvent(new Event(Events.ON_SELECT, itemList));


	}


 


	public void onSelect$itemList(){


		int id = ((Stock)itemList.getSelectedItem().getValue()).getId();


		detail.setSrc(DETAIL_URL + "?id=" + id);


	}	


 


	public void onChanging$searchBox(InputEvent event) {


		String key = event.getValue();


		LinkedList item = new LinkedList();


		List items = dao.findAll();


 


		if (key.trim().length() != 0) {


			for (Iterator iterator = items.iterator(); iterator.hasNext();) {


				Stock st = (Stock) iterator.next();


				if (st.getName().toLowerCase()


						.indexOf(key.toLowerCase()) != -1)


					item.add(st);


 


			}


			itemList.setModel(new ListModelList(item));


		} else itemList.setModel(new ListModelList(items));


	}


 


	public List getStocks(){


		return dao.findAll();


	}


}
 

当用户点击任何一支股票,onSelect事件被触发,onSelect$itemList()这个监听方法被执行,然后重新加载price.zul,显示这支股票的历史价格。

 

在表格和图中显示股票的历史价格

在PriceController.java中我们得到股票的历史价格的数据并为图表构建一个合适的模型。

PriceController.java

public class PriceController extends GenericAutowireComposer {


 


	private StockDAO dao = new StockDAO();


	private CategoryModel cateModel;			


	private List items;


 


	public PriceController() {


		init();


	}


 


	public void init() {


		//get stock id


		int id = Integer.parseInt((String) Executions.getCurrent().getParameter("id"));		


		Stock stock = dao.getStock(id);


		items = stock.getPriceItems();		


		//create category model for chart


		cateModel = new SimpleCategoryModel();


		for (Iterator iterator = items.iterator(); iterator.hasNext();) {


			Price price = (Price) iterator.next();


			cateModel.setValue(stock.getName(), price.getDate(), price.getClose());


		}


	}


	public List getPrices(){


		return items;


	}


	public CategoryModel getCateModel() {


		return cateModel;


	}	


}
 

 

Server+client混合模式

除了上面的纯粹的服务器编程方式,我们再介绍一种混合模式。 我们想提高搜索的响应速度,那可以把相应的代码移到客户端。下面我们用搜索功能做一个例子。

 

修改现有的代码

为了在客户端实现搜索功能,首先我们要加载股票数据到客户端,我们使用一个include组件从服务器端加载data.xml。

<include id="data" src="data.xml" comment="true"/>
 

 

其次在服务器端的控制器(StockController.java) 可以不要了,它的功能将在客户端实现。

<borderlayout id="main">
 

另外我们不再在服务器端生成股票列表了,把这部分相关的服务器端代码也除去。

<listbox id="list" rows="10" width="300px">
 

 

客户端编程

为了在客户端实现搜索功能,我们为listbox 创建一个更新方法来生成用户搜索的股票项目。

<zk xmlns:w="http://www.zkoss.org/2005/zk/client">


....


<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: ),因为这个监听器是在客户端的。

<textbox id="inp" w:onChanging="this.$f('list').update(event.data.value)"/>
 

此外,我们还要在一开始显示所有的股票,这需要调用注册一个bind_方法来实现初始化,这个方法将调用listbox的update方法。

<listbox id="list" rows="10" width="300px">


	<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事件。

<listbox id="list" onSelect="" rows="10" width="300px">


 

接下来,为了在服务器端处理onSelect事件, 我们在服务器端实现一个service,通过它我们可以实现股票历史价格的更新:

<listbox id="list" onSelect="" rows="10" width="300px">


....


</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,客户端/服务器端混合编程的方式没有去做。



 

  • 大小: 28.5 KB
  • 大小: 31.1 KB
7
1
分享到:
评论
2 楼 kangsg219 2009-09-21  
任何金融交易类软件在MT4面前都是残废!
1 楼 whg333 2009-09-20  
ZK性能貌似是个问题吧?而且还有它的商业协议问题...
不过ZK的基于事件驱动和Ajax服务器端的编程方式倒是不错...
WYSIWYG的ZK studio也很诱人...

相关推荐

    zk-src-5.0.7.1(zk源码)

    《Zookeeper源码解析——基于zk-src-5.0.7.1》 Apache ZooKeeper,简称ZK,是一款开源的分布式协调服务,它为分布式应用提供一致性服务,包括命名服务、配置管理、组服务、分布式同步和分布式锁等。在ZK 5.0.7.1...

    zk+spring+hibernate例子

    主要介绍了zk+spring+hibernate的使用方法 早期使用的是 hibernate的配置文件 后来 被改成了 引用注释的方式 老的绑定文件也没有删除,sql下面由数据库文件 导入mysql就可以,不错的教学例子 学习起来很简单

    zk5.0.7.1.chm

    zk5.0.7API 是ZK框架:Ajax开发实战对应的手册

    ZK+spring+hibernate的整合

    《ZK+Spring+Hibernate整合详解》 ZK、Spring和Hibernate是Java开发中的三大重要框架,它们分别在用户界面、依赖注入与事务管理、持久层操作方面发挥着关键作用。将这三者进行整合,可以构建出高效、稳定且易于维护...

    zk finger SDK 5.0

    ZK Finger SDK 5.0 是一款专门用于生物识别技术,特别是指纹识别的软件开发工具包。这个SDK为开发者提供了一整套的功能,使他们能够轻松地在自己的应用程序中集成指纹识别功能。以下是对该SDK及其相关文件的详细说明...

    zk教程+插件+例子

    ZK(Zookeeper)是一个分布式的,开放源码的分布式应用程序协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终将简单易用的接口和性能高效、功能稳定的系统提供给...

    zk+spring+hibernate整合

    在IT行业中,`ZK`(ZooKeeper)、`Spring`和`Hibernate`都是非常重要的技术组件,分别在分布式协调、应用框架和对象关系映射领域有着广泛应用。本项目是将这三个技术进行整合,用于构建一个基于MySQL数据库的完整...

    eclipse springboot+dubbo+zk+mybatis restful编程风格

    【标题】"eclipse springboot+dubbo+zk+mybatis restful编程风格"涉及的关键技术栈包括了Eclipse IDE、Spring Boot、Dubbo、Zookeeper以及MyBatis,并且采用了RESTful编程风格。这些组件共同构成了一个高效、可扩展...

    zk+spring+hibernate+mysql demo(2)

    使用zk+spring+hibernate+mysql做的demo,只需要修改下MySQL连接字符串就可以运行。因为容量 有点大。分卷压缩了,请先下载zk+spring+hibernate+mysql demo(),下全后解压。

    zk-bin-5.0.0-RC.zip_DEMO_fckez.jar_zk_zk demo_zk-demo-5.0.z

    综合以上信息,这个压缩包适合对Zookeeper感兴趣的开发者,他们可以通过运行`fckez.jar`、设置和启动`zk-bin-5.0.0-RC`,以及探索`zk_demo`或`zk-demo-5.0.z`来学习Zookeeper的使用、配置和API。通过这些实践,...

    ZK+Spring+Hibernate项目搭建

    综合来看,"ZK+Spring+Hibernate"项目搭建涉及了前端UI展现、后端业务逻辑处理、数据持久化和数据库管理等多个层面,这种技术栈的组合可以实现高度模块化的应用开发,便于团队协作和后期的维护升级。在实际操作中,...

    ZK + Spring + Hibernate

    ZK以其事件驱动模型和服务器端渲染技术而闻名,它简化了用户界面的开发,提供丰富的组件库,允许开发者无需编写JavaScript就能实现动态交互功能。 **Spring框架** 是一个全面的企业级应用开发框架,它支持依赖注入...

    zk+spring+hibernate+mysql Demo ()

    使用zk+spring+hibernate+mysql做的demo,只需要修改下MySQL连接字符串就可以运行。因为容量有点大。分卷压缩了,请下全后解压。

    dubbo+zk+ssm源码+dubbo-admin

    本资源包涵盖了"Dubbo+SSM+Zookeeper"这一经典组合,旨在帮助开发者更好地理解和运用这些技术,构建高效、可扩展的系统。以下是对各组件及其交互的详细解析。 一、Dubbo:高性能的服务框架 Dubbo是阿里巴巴开源的...

    zk客户端curator2.11

    客户端是Curator Framework,是Apache的项目,它主要的功能是为ZK的客户端使用提供了高可用的封装。在Curator Framework基础上封装的curator-recipes,实现了很多经典场景。比如:集群管理(Leader选举)、共享锁、...

    zk+sptingmvc+ibatis 系统

    "ZK+SpringMVC+Ibatis"是一个常见的企业级应用开发框架组合,它整合了三个强大的技术:ZK作为用户界面的展示层框架,SpringMVC作为控制层框架,而Ibatis则作为数据访问层的持久化工具。这个系统的构建旨在提供高效、...

    ZK32-1_library_zk_thinkkrz_zk32+9999zk.com_

    3. **开发环境**:使用ZK32 SDK时,开发者通常需要有合适的开发环境,如Visual Studio或其他支持C/C++编程的IDE,以便能够编译和调试利用这些库的代码。 4. **生物识别技术**:ZK32库的核心功能可能涉及多种生物...

    ZK+Spring+Hibernate jar包

    ZK+Spring+Hibernate jar包名稱

    zookeeper的客户端使用,图形化界面查看节点信息

    描述中提到的“启动bat脚本,输入连接ip”,这通常是指在Windows环境下,使用Zookeeper提供的zkServer.cmd脚本来启动服务,然后通过zkCli.cmd客户端工具连接到Zookeeper服务器。连接时,用户需要输入Zookeeper服务器...

    zk+sptingmvc+ibatis 项目案例

    1. **ZK框架**:ZK提供了事件驱动的组件模型,使得开发者可以通过拖拽和配置方式快速构建UI。了解ZK的组件体系、事件机制以及布局管理器是必要的。 2. **SpringMVC**:掌握SpringMVC的基本工作流程,包括请求的分发...

Global site tag (gtag.js) - Google Analytics