一、项目总体介绍
前一段时间的工作中,笔者大概用了两三个月开发了一个Web管理信息系统,使用的框架集为Struts2.3.1+Spring3.0+Hibernate3+Jquery EasyUI1.3.5,系统业务逻辑并不复杂,完成数据的采集(以问卷的形式)、计算处理和形成报告发布。EasyUI是一个很优秀的JS UI框架,使用简单方便,效果也还可以,是UI效果和带宽速度之间的一个折中之选。系统中还有新闻发布模块,用到了富文本编辑器,在比较了很多插件之后,选择了kindeditor,原因很简单,因为它有网上现成的和EasyUI结合的例子。另外生产图表时用到了JFreechart插件。系统开发运行环境为windows7下Myeclipse8.5+JDK1.6+Tomcat6.0+SqlServer2008R2。
二、关于EasyUI
EasyUI很方便使用,一般只需要在一个页面中导入一些文件之后,其他的页面都是嵌在当前页买中。EasyUI提供了很多组件,如layout、panel、tabs、datagrid等,只需要初始化这些组件,并提供相应的数据即可。每个组件都有两种方式声明或者创建,即使用标记元素的形式和使用js的形式。具体引用参见项目源码或者EasyUI官网提供的API。
EasyUI官网:http://www.jeasyui.com/index.php
EasyUI官方API:http://www.jeasyui.com/documentation/index.php
这里想补充说明一下两点,一是easyUI的tree的使用,二是这里的使用的fastjson插件。
首先说下tree。easyUI提供了两种加载方式的tree,即同步Tree和异步Tree。同步树就是一次性加载完所有的节点,异步树是指,当点击一个节点后,才展开其子节点,不是一次性加载完。下面讲解一下异步树和同步树的实例。
首先看下数据库设计。基本字段有:菜单ID、菜单名称、菜单URL、父菜单ID,其他。
1、异步树实现
效果图:
异步树实现,前端jsp比较简洁,代码如下
<ul id="layout_west_tree" class="easyui-tree"
data-options="
url : '${pageContext.request.contextPath}/menuAction!getTreeNode.action',
fit:true,
lines : true,
onClick : function(node){
loadTab(node);
}
">
</ul>
loadTab是自己定义的一个函数,这里不用管它。前台就这么多内容。下面看后台
action:
/**
* 异步树获取方法
*/
public void getTreeNode() {
List<Menu> list = null;
try {
list = menuService.getTreeNode(id);
} catch (Exception e) {
logger.error("获取树节点出错:"+e.getMessage(),e);
}
writeJSON(list);
}
easyUI使用json数据格式,所以这里调用了writeJSON将获取到的树节点数据(一个list)写到前台去。writeJSON是自己定义的一个方法,将list转为json并输出到前台。这里发现
menuService.getTreeNode(id)
有个参数id,这个id很关键。easyUI使用异步树的时候,每次点击节点时,easyUI会向后台传递一个参数id,就是当前点击的菜单节点的id,这样后台可以根据这个id,加载该节点的下一级子节点。我们看下getTreeNode(id)的实现
public List<Menu> getTreeNode(Integer id) throws Exception {
/*
* 这是异步加载方式的树。该方式需要从前台获得参数id,用来做查询参数。
*
* 此处如果直接返回TbCdxx 的list,在将数据写到JSon中时,json插件会不断的去查找给TnMenu的子节点,搜索所有的节点
* 最终将所有节点都查出来,影响性能。所以这里用Menu代替TbCdxx,使其脱离Hibernate机制,不自动加载所有节点
*/
List<TbCdxx> list = null;
List<Menu> mlist = new ArrayList<Menu>();
String hql = null;
if (id == 0) {
// 第一次查询时,前台传来的id为null,这时查询所有根节点
hql = "from TbCdxx t where t.tbCdxx is null";
} else {
// 第二次,根据父节点的id,查询父节点下的子节点
hql = "from TbCdxx t where t.tbCdxx.cdId = " + id;
}
list = menuDao.get(hql);
if (list != null && list.size() > 0) {
for (TbCdxx ts : list) {
Menu m = new Menu();
m.setId(ts.getCdId());
m.setText(ts.getCdName());
Map<String,Object> attributes = new HashMap<String, Object>();
attributes.put("url", ts.getCdUrl());
m.setAttributes(attributes);
Set<TbCdxx> set = ts.getTbCdxxes();
// 如果该节点有子节点。设置图表状态为折叠
if (set != null && !set.isEmpty()) {
m.setState("closed");
}
// 如果没有子节点,图标状态为打开
else {
m.setState("open");
}
mlist.add(m);
}
}
return mlist;
}