1、ZK与传统MVC框架的集成
由于ZK应用本质上也是基于标准Web技术Servlet框架,因此与其它MVC框架的集成没有什么特别的,
以一个典型场景为例——为一个现有的Web项目(前端采用WebWork+Freemarker+prototype)引入ZK技术开发新的页面和模块,主要集成工作包括:
- 页面集成方式1:在freemarker中嵌入iframe指向zul页面;
- 页面集成方式2:prototype打开新页签时url参数指向zul页面;
- 参数传递方式1:url后面跟参数;
- 参数传递方式2:WebWork的action中request.setAttribute,然后服务端forward转到zul页面;
- 参数传递方式3:WebWork的action中session.setAttribute,然后返回页面中iframe指向zul页面;
2、CSS样式定制
2.1、概述
ZK应用对于浏览器来说就是标准的Web页面,我们在ZUL页面或java代码中创建的每一个ZK组件在运行时都会被ZK引擎渲染生成标准的HTML+CSS+JavaScript代码,
并且ZK允许我们对所有组件的样式进行定制,例如如下代码就可以将button按钮组件的样式从灰色背景图圆角改变成蓝底白字直角的样子:
/* 覆盖默认按钮样式,实现蓝底白字按钮 */
.blue-button .z-button-tl,.blue-button .z-button-tr,.blue-button .z-button-bl,.blue-button
.z-button-br,.blue-button .z-button-tm,.blue-button .z-button-bm,.blue-button .z-button-cl,.blue-button
.z-button-cr,.blue-button .z-button-cm {
background-image
:
none
;
background-color
:
#2777C3
;
color
:
#ffffff
;
}
<button label=
"查询"
onClick=
"@command('query')"
sclass=
"blue-button"
width=
"65px"
/>
<button label=
"重置"
onClick=
"@command('reset')"
sclass=
"blue-button"
width=
"65px"
/>
|
通过Firebug等工具查看ZK页面的Dom可以方便的获得某个页面元素对应的样式是被那个zclass定义的,然后就可以有针对性的精确修改其样式;
2.2、三种定制方式
具体的有三种方式:
- 覆盖zclass:在页面<style>区域添加与ZK组件zclass同名的class,然后覆盖某些样式属性,这样就可以对该页面范围内的所有该组件样式进行修改;
- 定义sclass:像上面代码示例中那样定义自己的class,然后在需要应用的组件中指定sclass属性即可;
-
直接在组件的style字段中指定样式,例如
<
label
value
=
"红色粗体字"
style
=
"color:red;font-weight:bold"
/>
2.3、更多示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/* 菜单样式 */
.menuItem{ text-decoration:none;color:#a9ccf4; }
.menuItem:hover{ text-decoration:underline;color:#ffffff; }
.menuItem:visited{ text-decoration:none;}
.menuItemSelected{ text-decoration:none; color:#ffffff;font-weight:bold;}
<
div
>
<
div
id
=
"menuDiv"
style
=
"background-color:#2777C3;"
height
=
"30px"
>
<
hbox
align
=
"center"
vflex
=
"true"
>
<
separator
/>
<
separator
/>
<
a
label
=
"保全"
sclass
=
"menuItem"
>
<
custom-attributes
url
=
"/zuls/bqShiwu/bqShiwu.zul"
/>
</
a
>
<
separator
/>
<
label
value
=
"|"
style
=
"color:#ffffff"
/>
<
separator
/>
<
a
label
=
"交款"
sclass
=
"menuItem menuItemSelected"
>
<
custom-attributes
url
=
"/zuls/shiwu.zul"
/>
</
a
>
<
separator
/>
<
label
value
=
"|"
style
=
"color:#ffffff"
/>
<
separator
/>
<
a
label
=
"服务"
sclass
=
"menuItem"
>
<
custom-attributes
url
=
"/zuls/ServiceNetWork/serviceNetWorkQuery.zul"
/>
</
a
>
<
separator
/>
<
label
value
=
"|"
style
=
"color:#ffffff"
/>
<
separator
/>
<
a
label
=
"单证"
sclass
=
"menuItem"
>
<
custom-attributes
url
=
"/zuls/resendDocument/resendDocumentQuery.zul"
/>
</
a
>
</
hbox
>
</
div
>
<
div
id
=
"contentDiv"
>
<
include
id
=
"交款"
src
=
"/zuls/shiwu.zul"
hflex
=
"true"
/>
</
div
>
</
div
>
|
列表中超长文本自动换行
<
label
value
=
"${each.cityName}"
style
=
"word-wrap: break-word;"
/>
|
紧凑表格:去掉padding
<
style
>tr.z-row .z-detail-outer {padding:0 0 0 0}</
style
>
|
更多见官方文档 《ZK Style Customization Guide》、 http://books.zkoss.org/wiki/ZK%20Style%20Customization%20Guide/Upgrade%20Customized%20Style%20From%20other%20ZK%20Version/Upgrade%20From%20ZK%206.5
3、ZK与客户端JS的双向调用
3.1、服务端Java调用客户端JS
ZK支持在服务端Java代码中直接执行js,如:Clients.evalJavaScript("top.bodyIframe.main.tabsDetail.setActiveTab('010402')");//选中保单查询页签
如果要执行的JS很长,就不方便直接这样拼字符串了,可以:
- 在Zul页面中引入js文件:<script type="text/javascript" src="/js/life/telGPS/preserveDoc.js"></script>
-
或在<script>标签中直接写js:
<
script
type
=
"text/javascript"
>
function sendMessage(id){ var telNum = top.spani; zAu.send(new
zk.Event(zk.Widget.$('$preserveDisDocumentPopup'),'onSendMessage',{'':{documentId:id,tel:telNum}})); return;
}
</
script
>
如果要执行的js不仅长而且里面有很多变量,可借助freemarker渲染js文件,例如:
static
{
try
{
cfg =
new
Configuration();
cfg.setLocalizedLookup(
false
);
cfg.setClassForTemplateLoading(CheckIdentityCtrl.
class
,
"/com/xx/ctrl/policyCancel/"
);
jsTemplate = cfg.getTemplate(
"checkIdentity.js"
,
"UTF-8"
);
}
catch
(Exception e) {
e.printStackTrace();
throw
new
RuntimeException(e);
}
}
HashMap map =
new
HashMap();
map.put(
"customerName"
, selectedPolicy.getsPname());
map.put(
"policyNo"
, selectedPolicy.getPolicyno());
String js = FreeMarkerTemplateUtils.processTemplateIntoString(jsTemplate, map);
logger.debug(js);
Clients.evalJavaScript(js);
|
3.2、在ZUL页面中直接调用JS
<
script
type
=
"text/javascript"
>
function sendShortMessage(id){
var telNum = top.spani;
zAu.send(new zk.Event(zk.Widget.$('$testButton'),'onSendMessage',{'':{documentId:id,tel:telNum}}));
return;
}
</
script
>
<
window
xmlns:w
=
"client"
…………>
…………
…………
<
a
label
=
"发送短信"
w:onClick
=
"sendShortMessage('${each.documentId}')"
style
=
"color:red"
></
a
>
…………
…………
<
button
id
=
"testButton"
label
=
"这个按钮用来被js作为zAu通知目标"
onSendMessage
=
"@command('sendMassage',e=event)"
visible
=
"false"
></
button
>
|
3.3、JS调用ZK服务
客户端JS调用ZK服务也非常简单——通过zAu对象像某个组件发送事件,然后组件声明该事件触发command或服务端listen该事件处理即可;
示例代码如下:
<
script
type
=
"text/javascript"
>
function sendShortMessage(id){
var telNum = top.spani;
zAu.send(new zk.Event(zk.Widget.$('$testButton'),'onSendMessage',{'':{documentId:id,tel:telNum}}));//发送json对象调用ZK服务
return;
}
</
script
>
<
window
xmlns:w
=
"client"
…………>
…………
<
a
label
=
"发送短信"
w:onClick
=
"sendShortMessage('${each.documentId}')"
style
=
"color:red"
></
a
>
…………
<
button
id
=
"testButton"
label
=
"这个按钮用来被js作为zAu通知目标"
onSendMessage
=
"@command('sendMassage',e=event)"
visible
=
"false"
></
button
>
|
@Command
public
void
sendMassage(
@BindingParam
(
"e"
) Event e)
throws
Exception{
JSONObject json = (JSONObject) e.getData();
String documentId = (String)json.get(
"documentId"
);
String tel = (String)json.get(
"tel"
);
|