easyUI 的 Tree组件在大部分时候都要从数据库读取数据,本文基于Java语言来实现easyUI tree的异步加载。
先看一下实现的效果:
整个过程采用的是简单三层架构,无论采用哪种模式,只要弄懂tree的原理,都是可以实现的。使用其他语言的也可以作为参考。
话不多说直接上代码:
HTML代码:
<body>
<ul id='menu'></ul>
</body>
js代码:
<script type="text/javascript">
$(function() {
$('#menu').tree({
url : '${pageContext.request.contextPath}/menu'
});
});
</script>
url地址为:web层的servlet地址。 最基本的异步加载树只需要获取数据的地址即可。
注意 :jsp页面一定不要忘记引入easyUI的css样式和js库
无论何种架构,只需要明白tree请求的参数是该行数据的id即可,响应的是json格式数据。
接下来我们从底层先一步步的介绍代码,最后再统一的梳理。
一、首先,数据库为:
text为显示的内容,即名称;url为地址;seq为排序列 都是非必要字段。
二、其次:domain层用来存放实体类,domain层我们建两个实体类:一个是menu类对应着数据库,一个是treenode类对应的是easyUI tree需要的数据类型。
1、menu类:对应着数据库的字段
public class Menu {
private String id;
private String pid;
private String text;
private String status;
private String url;
/* get set 方法 此处省略*/
}
2、treenode类:对应着easyUI tree需要的数据类型
public class TreeNode implements java.io.Serializable{
private String id;
private String text; // 树节点名称
private String iconCls; // 前面的小图标样式
private Boolean checked = false; // 是否勾选状态
private Map<String, Object> attributes; // 其他参数
private List<TreeNode> children; // 子节点
private String state = "open"; // 是否展开(open,closed)
/* get set 方法 此处省略*/
}
三、dao层:获取数据库表中的数据
public class MenuDao {
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
//查询树节点数据
public List<Menu> selectTreeData(String id) throws SQLException {
String sql = "select * from menu where pid = ?";
if (id == null || id.trim().equals("")) {
id = "00000000-0000-0000-0000-000000000000";
}
return runner.query(sql, new BeanListHandler<Menu>(Menu.class),id);
}
//获取子级节点的数量
public int menuCountChildren(String id) throws SQLException {
String sql = "select count(*) from menu where pid = ?";
Long query = (Long) runner.query(sql, new ScalarHandler(),id);
return query.intValue();
}
}
selectTreeData()方法为获取数据库的数据,tree插件第一次请求时的参数id为null,所以需要根据null去数据寻找第一级节点,因为表中第一级pid为00000000-0000-0000-0000-000000000000,所以给id赋初始值。
menuCountChildren()方法为判断该节点下是否还有子级节点。
四、service层:业务层只起到一个数据传递的作用。
public class MenuService {
MenuDao dao = new MenuDao();
//获取树节点数据
public List<Menu> selectTreeData(String id){
List<Menu> list = null;
try {
list = dao.selectTreeData(id);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
//获取子级节点的数量
public int menuCountChildren(String id) {
int count = 0;
try {
count = dao.menuCountChildren(id);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return count;
}
}
五、web层:接收请求作出响应。
public class MenuServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//引用service层
MenuService service = new MenuService();
//接收树上传来的ID参数
String id = request.getParameter("id"); // 接收tree插件请求的参数 参数名为:id 第一次请求时为null 之后请求时 为该节点的id值 //
//接收后台传来的查询数据
List<Menu> menu = service.selectTreeData(id); // 获取后台查询的数据库数据,如果直接将menu转成json格式响应 给tree插件,因为不是tree插件需要的数据样式,显示不出来树形结构 //
//封装成easyUI tree的数据格式
List<TreeNode> treeNodes = new ArrayList<TreeNode>(); // 转换成tree插件需要的数据样式 //
for(Menu item : menu){
TreeNode treeNode = new TreeNode();
treeNode.setId(item.getId()); // 封装id
treeNode.setText(item.getText()); // 封装text
//创建一个容器,存放其他的参数
Map attributes = new HashMap(); // 创建Map容易,存放其他的参数,以备不时之需 //
attributes.put("url", item.getUrl());
treeNode.setAttributes(attributes);
//封装state
if (service.menuCountChildren(treeNode.getId()) > 0) { // 判断该级是否还有子级 如果有 默认不展开 //
treeNode.setState("closed");
}
treeNodes.add(treeNode);
}
Gson gson = new Gson();
String json = gson.toJson(treeNodes); // 将封装好的数据转换成json格式,响应给tree插件 //
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(json);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
至此,整个easyUI tree插件的异步加载数据就大功告成了。