Dorado on the way - final
本来想继续前面陆陆续续的两篇关于Dorado的文章,但想想为了大家查阅方便,干脆来一个final版,一次性写出来。
2006年12月25日
今天是圣诞节,进入公司已经四个月了,可是对公司的产品Dorado还几乎是一个门外汉,(我要说明一下,不是我太笨,刚刚进入公司就接受了一个传统项目的开发,再加之学校的事情,在此我想我应该声明一点,我还是一个大四的学生,快结束大学四年的学习了,到最后,乱七八糟的事情实在是太多了,这个报告那个报告的。)
Thomas(我们公司的产品经理),还有范经理,实在是不好意思,还有公司的同事,虽然我比他们中的好多人进入公司都早,可惜我不是最厉害的,至少现在不是。
到上个星期为止,学校的事情基本上已经完了,毕业设计的课题也选了,选的课题是《基于智能Agent的分布式移动计算处理》,本来一开始自作聪明,以为题目为“移动计算”嘛,就是移动设备的计算处理,智能Agent嘛~估计就是一种形式而已,我自从从大学二年级自学Java开始,接触了Java中的JavaSE和JavaEE两个体系,正好可以借此课题,让我对JavaME有所了解,也实现了完成毕业设计的作用。结果后来导师选好了以后,看着导师给的材料,我才知道,我陷入泥潭了~(导师,原谅我这么说,呵呵·)
今天是我真正学习Dorado的第一天,公司给了我一些资料,所以我信心十足,我要赶上公司的其他同事,呵呵~争取超过他们哦~已经习惯了要做到最好,我是不是太自大了??
还是跟我学习Java一样,首先在公司的官方网站(http://www.bstek.com/)下载了Dorado的最近版本,我下载的版本是Dorado-5.0 061129.1132,一并还下载了Dorado 5 快速入门,组件使用技巧,当然还有Dorado的API--我的最爱。
首先看了Benny(我们公司的CTO)录制的两段视频说明,依照Dorado安装自带的doradosample,把dorado的大致功能作了一个讲解说明,个人感觉dorado还是挺有市场前景的,只是需要更大的宣传。
好了,闲话不多说了,开始我的Dorado之旅吧~
首先,需要了解的是:视图模型Dorado开发当中非常重要的对象,它封装了Dorado的界面逻辑和操作逻辑,即主要包含什么数据dataset ,以及这些数据通过什么形式来展现。
下面是我今天学习中,觉得需要注意的一些地方和术语。
2. RecordIterator ri = dataset.recordIterator() ; 获取对dataset的迭代器引用。
3. 对dataset的遍历
while(ri.hasNext()){
Record record = ri.nextRecord() ;
// 对每条记录的操作
}
4. 可是通过getControl(“controlName”) ; 获取组件的引用
注意,这里得到的是Control对象,需要进行类型的强制转换。
5. ”Module数据坞”的说明。
1). 数据坞里面的dataset对象可以被不同的视频模型索引用,以达到数据共享的作用。
2). Module不应该包含任何的业务逻辑,这是一种良好的设计模式。
3). Module的创建和销毁由Dorado提供的容器来管理,可以当做一个Singleton来使用。
所以在绝大部分情况下,在Module里面添加非静态的属性都不是正确 (或者是不太明智)的做法。
4). Module中的dataset的创建和销毁使用dorado提供的容器来管理的,但开发人员可以强制通过scope和timeout来定制dataset的生命周期。
5). scope有三种取值,分别是request (默认),session , application。
需要特别注意的是,在同一个request中连续以不同的pageIndex ,pageSize , parameters的不同组合来获取Module中的dataset,但将获得多个不同的dataset 实例。
6). 如果为了提高效率而将scope设置为application ,则应该注意让此dataset中的数据量不要过大。常用在大型系统中的代码表。
6. 通过dataSet.getCurrent() ; 方法,可以从dataSet获取当前记录。由于dataSet具有
“当前记录”这个,所以大多数操作都是对“当前数据”来说的。
2. 在请求映射的过程中,dorado有着自己独特的,不同于Struts的映射机制,
例如:对于请求:action=”access.login.d”
access 与对应的controller的名称一致,
而login与对应的action的名称一致。
3. controller的clazz属性所表示的是用于处理这个请求的class ,类似于Struts中的 Action ,而提交的数据,就从Struts 中的ActionFrom转换成了Dorado的dataset.
4. 对于页面的访问安全控制(即只能通过dorado式的请求,而不容许以文件结构路径来访问,即../demo/XX.jsp),可以将view中的safe属性设置为true来控制。
或者通过dorado默认的setting中的security.accessChecher来控制。不过我可以自主创建一个AccessChecker类型的java类来进行控制。但需要将setting.xml里面的 “security.accessChecker”属性修改为自己创建的类路径。
5. 可以通过DoradoContext来访问dorado的上下文信息,并通过标记量来告诉dorado 的上下文从哪里获取需要的变量。
例如,
Object obj = doradoContext.getAttribute(DoradoContext.SESSION,”username”) ;
i18n
1. 你需要在i18n目录下新建一些I18N的properties类型文件。此类文件与java中的
一致,都是以键-值对的形式存在。
2. 在dataset中的Fields里面设置为${Resource.fileName.key}的形式进行设置。这个就
有点类似于JSP2.0中的EL,其中,fileName是资源文件的文件头,不包括_cn_ZH
等类似的字样。而key是在文件中的键。这些都是在系统的setting.xml中的
“common.locale.language”和“common.locale.country ”来进行的配置。同样,你可
以通过修改这两个属性来启用不同的I18N文件。
3. 对于动态更改用户的国际化资源的情况,可以使用
LocalHelper.getLocale(“language”,”country”),
ResourceManager.getInstance().setDefaultLocale(context,
DoradoContext.SESSION,
locale) ; 来设置。
EL
在JSP2.0方面的书籍中有大量的经典介绍,这里就不再记录。
开发时,只需记住Dorado内置的隐式变量,即可。
Skin
1. 皮肤文件夹存放的位置是在skins文件夹下面的。
在使用新皮肤时,只需要修改setting.xml中的view.smartweb2.skin对应的值即可。
2. 同时可以通过修改skin.css文件来修改dorado中的标签库的所有展示风格。
3. 同时也支持传统的JSP开发,即在<head>标签中设置相信的各种属性,以完成让
dorado以用户自定义的形式进行展现。
2007年1月1日
关于Dataset
可以通过RecordIterator 对dataset中的数据进行遍历(包括已经在客户端“删除”的记录)。
为什么在客户端已经“删除”的记录,dataset仍然可以遍历到?
原因就在于Dorado出于对性能的考虑,在客户端做的删除并没有立刻更新服务器段的记录,而仅仅是在客户端的dataset中做了删除的标记。在用户提交了以后,才会对服务器端的记录做修改。所以用户在客户端做的删除操作后,如果刷新页面,删除的记录将会重新出现。
可以通过如下代码对dataset中已经标记为“删除”的记录进行遍历:
RecordIterator rit = dataset.recordIterator() ; // 获取dataset的遍历器
rit.setVisibility(Dataset.FILTER_DELETED) ; // 设置遍历器的可见属性
while(rit.hasNext()){
Record record = rit.nextRecord() ; // 取得当前的Record对象
// 对记录进行操作
}
isFirst 以及 isLast的理解
在dataset中容易犯下的错误就是对isFirst和isLast的误解。
isFirst和isLast并不像大家想象当中的那样,代表着Dataset的当前记录(注意,所有对Dataset的操作,都是对“当前记录”而言)是否是第一条记录或者是最后一条记录。他们真正的含义如下:
isFirst:
官方解释:
isFirst表示Dataset已经在试图继续向前移动当前记录的过程失败,亦即当dataset的当前记录从第二条记录转到第一条记录时isFirst仍然是 false,只有当Dataset试图继续向前移动当前记录后,isFirst才会变成 true,此时dataset的当前记录仍然是第一条记录。
我的理解:
对于isFirst,你可以于Java当中的Iterator作对比。我们假设Java中的 Iterator具有previous(),就是next()倒着遍历(),那么当当前记录从第二条作previous()成功到达第一条记录的时候,isFirst仍然返回false,为什么?因为在移动过程中没有受阻,它成功的前移了。下面要注意了,现在当前记录已经在第一条了,现在如果当前记录再试图向前移动时,此时受阻了,因为在当前记录前面已经没有记录可以移动了,此时 isFirst()返回true。
如下图:
在dorado的设计过程中,数据导航条的数据前移和后移过程中,并不会查看当前记录是否是第一条或者是最后一条数据,而是默认前或者后还有数据,从而继续作向前或向后的操作,只有在移动受阻后,才修改是否到边界的标记,这样或许在移动操作中可能会对移动的性能有一定的帮助。
个人认为,这里把isFisrt()看作是对当前记录的操作时候“越界”的标志更为合适。
IsLast:
官方的解释:
isLast表示Dataset已经在试图继续向后移动当前记录的工程失败,亦即当dataset试图继续向前移动当前记录后,isFirst才会变为true,此时 Dataset的当前记录仍然是倒数第一条记录。
我的理解:
可以对比isFirst来理解,我觉得我已经解释的比较清楚了。
moveFirst 和 moveLast方法
当用户调用了Dataset的moveFirst或moveLast之后,Dataset的isFirst或isLast立刻被置为true。
当dataset没有任何可见记录的时候,isFirst和isLast将同时为true,并且当前记录为null。
想必在前面理解了我对isFirst和isLast的讲解之后,对这两个方法的理解应该不会出现什么偏差了。
不过我想提醒大家一下,注意我这里的用词,是“可见记录”,即是说,如果在客户端删除了所有的记录,虽然没有向服务器提交,但此时isFirst和isLast都会同时返回true。这里就很好的统一了对用户的“体验一致性”,即用户认为已经没有数据了。
不知道大家有没有在浏览器中查看过Dorado生成的jsp文件的源代码,其实这些源代码都是通过html和xml界面模板信息共同展现的。
Dorado内部加载顺序:第一步: 客户端发出请求
第二步:初始化 视图模型
第三步:初始化 Dataset
第四步:初始化 组件
第五步:完成组件与Dataset之间的绑定
第六步: Dataset向外部请求数据,完成数据加载
第七步:向客户端返回HTML/XML界面模板信息
第八步:完成,显示页面
2007年1月8日
Dataset中最重要的方法: flushData()
功能我想我不说大家也知道,就是通过不刷新页面来实现数据更新与交换。
在dataset中设置autoLoadData为false,并且设置async为true。
case “key1” : {
// code here
}
...
}
记录状态
none -无状态: 当数据下载到客户端,此时记录是“无状态”的,这是 Dorado的默认状态。
new -新增状态:表示该记录刚刚被添加到数据集,并且尚未得到验证和确认。如果此时我们执行了对该记录的撤销,那么该记录将被从数据集中移除。
insert -已添加状态:表示这是一条新增的并且已经经过验证和确认的记录。
modify -已修改状态:表示这是一条数据已经被修改的并且已经经过验证和确认的记录。
delete - 已删除状态:表示这是一条被标记为已删除的记录。默认形式下此种记录是不可见的,我们对数据集的遍历操作也不会得到该记录。但是我们前面还是接受了一种方法,可以遍历到这类记录。
可以通过Rocord.getState()方法获得记录的状态信息。
并且可以通过dataset.getOldRecord(Record r)来获取记录r的原始值。
组件开发
一. DataTable
分配下载功能: 设置autoLoadPage为true
在表格中,列标题常常需要汉化成为中文,我们不建议您在DataTable里直接修改,尽管这样做也可以达到目的,我们建议您在与DataTable绑定的Dataset中的Fields中进行修改。
设置fixedColumn来设置锁定的列数。
设置confirmCancel和confirmDelete属性可以设置对表格进行快捷键的操作时,是否弹出相应的提示信息。
设置editable来设置表格是否可编辑。
通过headerHeight可以设置表格头的高度。
ignored属性是控制表格向客户端输出,一旦设置为true,在客户端将不会有这个表格元素存在。
top和left用来设置表格在屏幕的绝对位置。
在修改事件的时候,返回值为false,表明不需要再继续执行系统默认的执行方式,而只执行我们自定义的执行方式即可。
我们可以通过dataset.getField(“fieldName”).setReadOnly(true) 来控制具体某一个单元格的只读属性。
对表格可编辑状态控制的具体总结:
行状态:利用dataset的afterScroll动态设定dataset的readOnly属性实现。
列状态:利用column的readOnly属性实现。
指定m行n列的所在单元格状态:在dataset的afterScroll动态设定field的readOnly属性实现。