开始的感觉都还不错,把原来为公司做POC的一个项目拷贝过来修改修改就可以跑了,在本地基本可以用,但是有些问题:
- 添加修改数据的窗口不能用Modal窗口,错误消息是:Event processing thread is disabled(这个是因为ZK+GAE本来就需要把事件线程disable掉,因为GAE里面不能开线程)
- 把Modal窗口修改成Popup窗口,本地是好的,但是上传到GWT没有反应也没有报错。
开始的感觉都还不错,把原来为公司做POC的一个项目拷贝过来修改修改就可以跑了,在本地基本可以用,但是有些问题:
本来打算那个Notes-all用Google的全套解决方案的,就是用GWT + Google App Engine,看了下GWT的Sample,发现还是比较麻烦,但是感觉思路和ZK还是很像的,就打算比较下GWT和ZK,结果发现有人说可以把ZK成功发布到Google App Engine,试了下,果然是可以的,有兴趣的可以试试(在ZK网站可以下载zk-gae的sample,基于这个很容易建立自己的工程)。
基于我玩过一段时间的ZK,当然用ZK更方便了。
今天把原来的东西复制过去了,在做国际化的时候,用Eclipse编辑properties文件,里面有中文,不能保存,只能保存ISO-8859-1编码的内容。后来想着应该装个插件,下载了,好使,但是运行起来发现并没有把转码的内容显示为正确的中文,很奇怪。后来怀疑ZK读取properties文件的时候和Java读取国际化文件不一样,把properties文件的编码修改为UTF-8,然后直接用文本编辑器输入中文内容,运行测试,正常!
这个就是一般的国际化处理的经验造成的问题。
最后说一下,对ZK的这个违反Java惯例的方式赞一下,因为我一直对Java的这个需要把properties国际化文件用native2ascii转换的过程很鄙视,不知道谁这么设计的。ZK是以UTF-8读取properties文件的,不做任何转换。
更新:
可以修改Eclipse,让它对properties文件不强制使用ISO-8859-1编码保存:
eclipse –> window –> Preferences –> General –> Content Types –> Text –> 单击 Java Properties File,把底部的Default edcodng从ISO-8859-1改成utf-8,然后update。
昨天说了ZK的国际化做得不够好,今天稍微试了下,发现昨天提到的方案是可行的,创建一个Initiator,自动的把文本替换为国际化的内容:
<?init class="xxx.I18nBinderInit"?>
<toolbarbutton label="button.add" image="../images/add.png" onClick="userListWindow.onAdd()"/>
这个只是原型,现在可能还不能处理所有的组件类型,可以简单的修改下变成通用的解决方案:
增加一个Property文件,里面添加需要处理的组件类型以及需要处理的属性,然后读取这个配置,如果谁觉得不够可以在classpath中放置一个同名的配置文件进行定制。
源代码:
官方文档中说国际化很简单,资源文件放在WEB-INF下,文件名固定,都是i3-label.properties,简体中文的就是i3-label_zh_CN.properties。
按照官方文档说的,修改Locale就是:
session.setAttribute(Attributes.PREFERRED_LOCALE,xxxLocale)
但是根本不好使,后来搜索了下,发现需要设置:
Locales.setThreadLocal(xxxLocale)
另外一个问题是页面的刷新是个问题,如果不考虑用户已有的操作,假设用户进入首页没有做什么事情,首先改变Locale,那么刷新比较简单:
Executions.getCurrent().sendRedirect(“”)
国际化在页面中使用也比较丑陋,先是:
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c" ?>
…
<toolbarbutton label="${c:l(‘button.add’)}" image="../images/add.png" onClick="userListWindow.onAdd()"/>
比较理想的应该是像数据绑定一样,能够声明某个东西,然后Label的内容都从资源文件取:
<?init class="xxx.I18nBinderInit"?>
<toolbarbutton label="button.add" image="../images/add.png" onClick="userListWindow.onAdd()"/>
当然,这个功能可能自己也可以自己实现,有时间我会试试。
最后说的一点就是zk的默认中文是繁体中文,比较难受。
ZK很好的一个功能就是打开一个zul文件把组件添加到页面上:
Executions.createComponents(“yyy/xxx.zul”, null, params)
但是用这种方式打开的页面有一个奇怪的问题,和直接加载的不同,直接加载的的那些image是写相对路径的,例如:
<toolbarbutton label="Add" image="../images/add.png"/>
如果是用createComponents打开,这个方式不好使,找不到图片,显示一个红叉叉,需要修改成:
<toolbarbutton image="images/add.png"/>
ZK的分页功能默认是在客户端做的,也就是服务器端返回所有的结果,然后客户端每次显示一页的数据,翻页的时候不提交请求到服务器端重新查询。如果服务器端返回的结果比较多,这种方案就不太好了,要实现服务器端的分页也很简单,在使用Listbox或者grid的时候不要使用mold="paging",而是添加一个Paging组件:
<paging id="groupListboxPaging" pageSize="10"/>
然后给Paging增加事件监听:
final Paging paging = getPaging(pagingName);
paging.addEventListener(
"onPaging", new EventListener()
{
public void onEvent(Event event)
{
PagingEvent pagingEvent = (PagingEvent) event;
int pageNumber = pagingEvent.getActivePage();
int firstRow = pageNumber * paging.getPageSize();
queryInfos.get(listName).getPageInfo().setFirstRow(firstRow);
refreshList(listName);
}
});
代码中的getPaging和refreshList都是我自定义的方法,getPaging很简单,因为我的这个代码是在自定义的Window类里面的,所以:
protected Paging getPaging(String pagingName)
{
return (Paging) getFellow(pagingName);
}
而refreshList就比较复杂一些了,根据传入的list的名字查询结果并刷新list:
public void refreshList(String name)
{
try
{
getListbox(getListboxName(name)).setModel(new BindingListModelList(list(name), false));
}
catch (Throwable t)
{
handleException(t);
}
}
核心就是拿到Listbox或者Grid然后setModel。
这几天一直在研究ZK,感觉是我做web开发以来见到的最好的Web的UI框架。
美国那边的Consultant在给我们做UI,但是他们的UI的框架还在开发中,而且好像还在根据我们的一些要求不断的修改他们自己的框架,所以进度很慢,上个星期给了一个final drop,但是问题多多,发了一个问题列表,到现在也没有任何回应,我就趁着这个功夫用ZK做了一份功能和UI类似的,从代码量上讲比那个少,而且最重要的是UI的代码很干净整洁。
以后会大力推广这个东东,把我的经验都整理出来。
前几天抱怨没有好的Web框架,Bob推荐了ZK,这几天有时间的时候试了下,感觉确实不错。
用ZK做原型确实不错,数据都可以是hardcode的,ZK的文档基本上都是在这种模式下的,但是我打算做的是那种真正可以运行的demo,可以连接我们的后台Service跑的,这样搞的时候发现Sample奇缺,也没有好的最佳实践,主要是ZK本身确实很灵活,既可以在view里面嵌script实现,也可以写类来实现,而且也可以写类来创建组件,慢慢的摸索了下,根据自己的偏好搞出基本的东西来了。以后有时间搞完善了就放出来给大家参考吧。
ZK的几个主要问题:
我比较认可的特性:
© 2024 解惑
本主题由Anders Noren提供 — 向上 ↑