zk数据绑定

30 篇文章 0 订阅
14 篇文章 0 订阅

简介

关于数据绑定:数据绑定是一种机制,在UI组件和数据源之间自动完成数据复制。应用开发人员只需告诉绑定管理器UI组件和数据的联系。然后数据绑定期会自动完成加载(将数据加载到UI)并保存(UI保存到数据源)

 

关于zk的注解:zk中的注解不同于java中的注解,zk注解有两种形式,

 

1,基于标签的 如<a:bind value="person.address.city"/>,仅用于页面

 

2,类似el表达式,只是el表达式里用$而zk注解使用与java中的注解符号@相同

    如 <label value="@{indexWin$composer.totalScore}"> 仅用于页面。

    zk注解功能比较单一不能执行类似el中的${1+1}功能,仅可以用于对象图浏览解析显示,

    当然zk注解提供converter属性可以对显示或保存的数据类型进行转换,这个是el表达是没有的

 

zk注解与数据绑定紧密联系一起的,但数据绑定不一定使用注解的方式!

 

 

开发环境:

 

1,zk5.0.7.1

 

2,jdk1.6

 

3,eclipse3.6

 

 

下面我们从一个例子讨论一下基于注解的一般开发流程:

 

 

一,数据绑定的一般流程

二,创建UI页面

 

UI页面的创建并不一定要放在第一步,因开发团队或个人考虑的是数据还是原型设计而异。

 

1,让eclipse识别zul结尾的文件:

 

     与jsp、aspx类似,zk也创建自己的标签,这个标签集,

 

     zk给它起了一个名字叫ZUML(zk用户界面标记语言),

 

     zuml语言基于xml,符合xml语法规范。

 

     我们根据zuml的规范书写的文件,通常以*.zul扩展结尾,

 

     但eclipse不识别该文件。识别该文件有什么好处呢?语法着亮、自动提示、标签自动完成、验证文档的正确性

 

     下面介绍如何让eclipse识别zul扩展文件:

 

      eclipse菜单->window -> Preferences ->General ->Content Types -> Text -> xml ->

 

     下部扩展列表右侧 点击Add  -> 输入*.zul保存

 

 

 

 

 

2,创建zul文件

 

<?xml version="1.0"?>
<window id="indexWin" apply="com.sun4love.zk4love.web.controller.IndexController"
	xmlns:w="client" xmlns:n="native" xmlns="http://www.zkoss.org/2005/zul"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
	<grid model="@{indexWin$composer.users}"><!-- 注意$前半部分与apply类当前元素的id相同 -->
		<rows>
			<row self="@{each=user}" value="@{user}"><!-- self=@{each=user}表示将each变量名修改为user -->
				<label value="@{user.name}"></label>
				<combobox readonly="true" selectedItem="@{user.score}"
					forward="onChange=onReCalculate"> <!-- 将onChange事件转发给onReCalculate -->
					<comboitem label="0分" value="${0}"></comboitem>
					<!-- 因为value的值zul页面直接写0的话,zk把他作为String类型,此处用一个小技巧,设置value为数字类型 -->
					<comboitem label="1分" value="${1}"></comboitem>
					<comboitem label="2分" value="${2}"></comboitem>
					<comboitem label="3分" value="${3}"></comboitem>
				</combobox>
			</row>
		</rows>
		<foot>
			<footer>
			</footer>
			<footer>
				总得分:
				<label value="@{indexWin$composer.totalScore}"></label><!-- 与IndexController类的getTotalScore对应 -->
			</footer>
		</foot>
	</grid>
</window>

 

 

    注意要点:

 

         1)声明window组件,设置id为indexWin并applyuse与apply的区别IndexController类,

 

              另外还声明定义了clientnative命名空间。有几点非常重要,window的id、use与apply的区别、

 

              以及apply常用的几个composer

 

        2)grid的绑定数据模型,model="@{indexWin$composer.users}">,

 

             这里的model器类似swing中的model,是一个数据容器,model的值会根据@{}

 

             注解解释后的结果自动封装为如下不同的model,

 

              BindingGroupsListModel、 

 

             BindingListModelArray、

 

             BindingListModelList、

 

              BindingListModelMap、

 

             BindingListModelSet

 

              GroupsListModel

 

             然后分析注解@{}内的表达式,该表达式与el表达式里的对象图浏览完全一样, 没任何区别!

 

             解析过程:在作用域内查找indexWin$composer对象,①然后在indexWin$composer

 

                             查找getUsers方法,

 

             特殊情况:如果indexWin$composer.user.address.name中的name为null

 

                            或根本没有getName方法或address为空时会发生什么呢?解释过程会重复步骤①

 

                            a)无getName方法时,显示效果如下

                               

 

                                  看到类似Address@ec9441的东西,应该知道这是直接显示对象地址了!

 

                                 结合Address@ec9441出现的位置,我们应该会很快找出错误!

 

 

                          b)name为null或address为null时:都会得到正确的结果,这里不再解释

 

           3)indexWin$composer名字很奇怪,从哪里来?

 

                在2,1)中我们知道window的id为indexWin,indexWin$composer中$前半部分为组件的id


                window是component,如果window替换成<div id="someCompId">,

 

                此时indexWin$composer就变成了someCompId$composer, 那么$composer是什么?

 

                $composer是一个固定格式, 由apply的IndexController设置的,关于IndexController的详细内容

 

                将在下文介绍。indexWin$composer表示IndexController的实例对象,由zk自动创建。

 

                 获得更多bean的控制   apply bean与spring的整合 ,在此抛砖引玉

 

           4)注解中重命名each变量

 

               <!-- self=@{each=user}表示将each变量名修改为user -->

 

               <row self="@{each=user}" value="@{user}">

 

           5) UI到Object bean的自动保存

 

                 传统web开发中,例如注册用户,需要很多繁琐的步骤:提交表单,服务器端request.getParameter()

 

                  获取表单属性,并创建bean对象, 将表单值封装为bean对象,但request.getParameter()

 

                  获取值的仅为字符串,并且bean通常又是一个由多类型组成的状态对象,因此我们还要写一堆的

 

                   类型转换代码。在zk中,UI到bean对象和bean对象到UI的数据类型转换即封转都是自动完成的,

 

                  当然zk数据绑定器并不是万能的,zk提供了一个接口,由开发人员实现,但大部分我们无需

 

                  自定义转换器!

 

                  看看下面这张图,"懒程序员"们开始头疼了,但zk已经很简单的转换成你需要的对象!

 

 

       下面我们通过一个测试,看看zk的数据绑定器做了什么

 

       测试:改变下拉别表,看是否调用score的setter方法,如果调用,zk注解自动保存了选择的值到

                user的score属性上

 

<combobox readonly="true" selectedItem="@{user.score}"
	forward="onChange=onReCalculate"> <!-- 将onChange事件转发给onReCalculate -->
	<comboitem label="0分" value="${0}"></comboitem>
	<!-- 因为value的值zul页面直接写0的话,zk把他作为String类型,此处用一个小技巧,设置value为数字类型 -->
	<comboitem label="1分" value="${1}"></comboitem>
	<comboitem label="2分" value="${2}"></comboitem>
	<comboitem label="3分" value="${3}"></comboitem>
</combobox>

 

 

	public void setScore(Long score) {
		System.out.println("得分:"+score);
		this.score = score;
	}

 

      测试过程如图:

      

 

 

 

          6) 事件转发

 

                 下面这段的意思是将combobox的onChange事件转发给某个组件的onReCalculate事件

 

                  onReCalculate是谁的事件呢?zk开发中关于forward属性的那点事 这篇文章详细讲解了forward

 

                  的用法。

 

                 <combobox forward="onChange=onReCalculate">

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值