最近几个项目都用到了EasyUI这个Jquery框架,目前感觉起来还是很好使的,展示效果很好,帮助文档什么的资料很多,而且互联网上Easy粉很多,大多数拥护和喜爱EasyUI的粉丝们都愿意在网络平台互相分享学习成果,甚至有专门的社区来讨论使用情况,网址是http://bbs.jeasyuicn.com/,里面的资源模块里有很多都是免费的学习资料,包括视频文档项目源码等,建议初学者去看视频,然后研究一下这个网站(sypro)的实现http://sshe.jeasyuicn.com/,甚至有视频教程教大家怎么实现这个项目。互联网是一个巨人,他博学多才,期待能站在巨人的肩膀上开开眼界,学习到更多的知识技能,对于将来或现在的工作都是一个很大的收获。

  本篇博客是对EasyUI中树的实现的总结。如果想要展示一棵树,有很多方式,当然要分析你的需求。如果是展示省市区、学校、部门等大数据的话,建议还是使用异步加载。当然如果只是展示几个几乎不变的菜单项,就可以扁平化的展示你的数据了。

  首先介绍怎么实现一棵异步树。

  项目前准备:

  1、首先你要搭建一个你熟悉的框架环境,然后再前台加入EasyUI的源码包,并在页面引入js和css等文件。本文的实例主要讲解怎么实现树,以SSH框架为例。如果还有不懂怎么搭建EasyUI框架的同学,可以在EasyUI的中文社区里找EasyUI的初级视频来看看,非常简单的。

  2、建立数据库,比方说我们要通过树来展示你的菜单,那么就要先看一下EasyUI中tree的Data Format,也就是说我们要了解后台传给前台什么样式的Json格式。

  

  从上面的文档截图可以看出,他的数据格式有以下属性:id,text,state,checked,attributes,children;

  我们在设计数据库的时候,可以尽量的将节点id和节点名称分别设置成id和text,这样在前台解析Json的时候就能直接认出这些属性值,并显示出数据来。当然利用扩展的方式的话,你可以不必按照这些规范来,但是需要在tree控件里传入几个参数来传入属性值。

  首先,建立一个t_menu表:(注释如图)

  

  外键:

  

  测试数据:

  

  准备完以上的内容之后,我们开始做demo。

  1、加入EasyUI的树控件:

  1. <ul id="menuTree" class="easyui-tree" data-options="url:'<%=basePath%>menuAction!getTreeNode.action',parentField:'pid',lines:true,onLoadSuccess:function(node, data){$(this).tree('collapseAll')}"></ul>

 解析:

data-options里的URL是Action的路径,p

arentField设置成我们model里的pid,

lines:true用来显示树节点前的加减号,

onLoadSuccess:function(node, data){$(this).tree('collapseAll')}用来设置关闭所有的树节点。

  加入扩展js:

  

  1. $.fn.tree.defaults.loadFilter = function (data, parent) {
  2. var opt = $(this).data().tree.options;
  3. var idFiled,
  4. textFiled,
  5. parentField;
  6. if (opt.parentField) {
  7. idFiled = opt.idFiled || 'id';
  8. textFiled = opt.textFiled || 'text';
  9. parentField = opt.parentField;
  10.  
  11. var i,
  12. l,
  13. treeData = [],
  14. tmpMap = [];
  15.  
  16. for (i = 0, l = data.length; i < l; i++) {
  17. tmpMap[data[i][idFiled]] = data[i];
  18. }
  19.  
  20. for (i = 0, l = data.length; i < l; i++) {
  21. if (tmpMap[data[i][parentField]] && data[i][idFiled] != data[i][parentField]) {
  22. if (!tmpMap[data[i][parentField]]['children'])
  23. tmpMap[data[i][parentField]]['children'] = [];
  24. data[i]['text'] = data[i][textFiled];
  25. tmpMap[data[i][parentField]]['children'].push(data[i]);
  26. } else {
  27. data[i]['text'] = data[i][textFiled];
  28. treeData.push(data[i]);
  29. }
  30. }
  31. return treeData;
  32. }
  33. return data;
  34. };

  2、Action类实现

  首先是model类TMenu.java,映射数据库的类。

  

  1. import java.util.HashSet;
  2. import java.util.Set;
  3. import javax.persistence.CascadeType;
  4. import javax.persistence.Column;
  5. import javax.persistence.Entity;
  6. import javax.persistence.FetchType;
  7. import javax.persistence.Id;
  8. import javax.persistence.JoinColumn;
  9. import javax.persistence.ManyToOne;
  10. import javax.persistence.OneToMany;
  11. import javax.persistence.Table;
  12.  
  13. /**
  14. * TMenu entity. @author MyEclipse Persistence Tools
  15. */
  16. @Entity
  17. @Table(name = "t_menu", catalog = "easyui")
  18. public class TMenu implements java.io.Serializable {
  19.  
  20. // Fields
  21.  
  22. private String id;
  23. private TMenu TMenu;
  24. private String text;
  25. private String iconCls;
  26. private String url;
  27. private Set<TMenu> TMenus = new HashSet<TMenu>(0);
  28.  
  29. // Constructors
  30.  
  31. /** default constructor */
  32. public TMenu() {
  33. }
  34.  
  35. /** minimal constructor */
  36. public TMenu(String id) {
  37. this.id = id;
  38. }
  39.  
  40. /** full constructor */
  41. public TMenu(String id, TMenu TMenu, String text, String iconCls, String url, Set<TMenu> TMenus) {
  42. this.id = id;
  43. this.TMenu = TMenu;
  44. this.text = text;
  45. this.iconCls = iconCls;
  46. this.url = url;
  47. this.TMenus = TMenus;
  48. }
  49.  
  50. // Property accessors
  51. @Id
  52. @Column(name = "id", unique = true, nullable = false, length = 36)
  53. public String getId() {
  54. return this.id;
  55. }
  56.  
  57. public void setId(String id) {
  58. this.id = id;
  59. }
  60.  
  61. @ManyToOne(fetch = FetchType.LAZY)
  62. @JoinColumn(name = "pid")
  63. public TMenu getTMenu() {
  64. return this.TMenu;
  65. }
  66.  
  67. public void setTMenu(TMenu TMenu) {
  68. this.TMenu = TMenu;
  69. }
  70.  
  71. @Column(name = "text", length = 100)
  72. public String getText() {
  73. return this.text;
  74. }
  75.  
  76. public void setText(String text) {
  77. this.text = text;
  78. }
  79.  
  80. @Column(name = "iconCls", length = 50)
  81. public String getIconCls() {
  82. return this.iconCls;
  83. }
  84.  
  85. public void setIconCls(String iconCls) {
  86. this.iconCls = iconCls;
  87. }
  88.  
  89. @Column(name = "url", length = 200)
  90. public String getUrl() {
  91. return this.url;
  92. }
  93.  
  94. public void setUrl(String url) {
  95. this.url = url;
  96. }
  97.  
  98. @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "TMenu")
  99. public Set<TMenu> getTMenus() {
  100. return this.TMenus;
  101. }
  102.  
  103. public void setTMenus(Set<TMenu> TMenus) {
  104. this.TMenus = TMenus;
  105. }
  106.  
  107. }

  其次是model类Menu.java,此处的model是pageModel,是为了接应前台的name值的:

  

  1. public class Menu {
  2.  
  3. private String pid;//父菜单ID
  4. private String pText;//父菜单名称
  5. private String id;//子菜单Id
  6. private String text;//子菜单名称
  7. private String iconCls;//子菜单图标
  8. private String url;//子菜单路径
  9. private String state;
  10.  
  11. //---------------set/get--------------
  12.  
  13. public String getPid() {
  14. return pid;
  15. }
  16. public void setPid(String pid) {
  17. this.pid = pid;
  18. }
  19.  
  20. public String getpText() {
  21. return pText;
  22. }
  23. public void setpText(String pText) {
  24. this.pText = pText;
  25. }
  26. public String getId() {
  27. return id;
  28. }
  29. public void setId(String id) {
  30. this.id = id;
  31. }
  32.  
  33. public String getText() {
  34. return text;
  35. }
  36. public void setText(String text) {
  37. this.text = text;
  38. }
  39. public String getIconCls() {
  40. return iconCls;
  41. }
  42. public void setIconCls(String iconCls) {
  43. this.iconCls = iconCls;
  44. }
  45. public String getUrl() {
  46. return url;
  47. }
  48. public void setUrl(String url) {
  49. this.url = url;
  50. }
  51. public String getState() {
  52. return state;
  53. }
  54. public void setState(String state) {
  55. this.state = state;
  56. }
  57.  
  58. }

  

  Action类:

  

  1. package com.action;
  2.  
  3. import org.apache.struts2.convention.annotation.Action;
  4. import org.apache.struts2.convention.annotation.Namespace;
  5. import org.apache.struts2.convention.annotation.ParentPackage;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7.  
  8. import com.pageModel.Menu;
  9. import com.service.IMenuService;
  10.  
  11. import com.opensymphony.xwork2.ModelDriven;
  12.  
  13. @ParentPackage("basePackage")
  14. @Namespace("/")
  15. @Action(value="menuAction")
  16. public class MenuAction extends BaseAction implements ModelDriven<Menu> {
  17. Menu menu=new Menu();
  18. @Override
  19. public Menu getModel() {
  20. // TODO Auto-generated method stub
  21. return menu;
  22. }
  23. private IMenuService menuService;
  24.  
  25. public IMenuService getMenuService() {
  26. return menuService;
  27. }
  28. @Autowired
  29. public void setMenuService(IMenuService menuService) {
  30. this.menuService = menuService;
  31. }
  32. /**
  33. * 异步获得树节点
  34. */
  35. public void getTreeNode(){
  36. super.writeJson(menuService.getTreeNode(menu.getId()));
  37. }
  38. }

  2、了解getTreeNode()方法的实现:  

  对应service的实现类:

  1. package com.service.impl;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Set;
  8.  
  9. import org.springframework.beans.BeanUtils;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.stereotype.Service;
  12.  
  13. import com.dao.IBaseDao;
  14. import com.model.TMenu;
  15. import com.pageModel.Menu;
  16. import com.service.IMenuService;
  17.  
  18. @Service("menuService")
  19. public class MenuServiceImpl implements IMenuService {
  20. private IBaseDao<TMenu> menuDao;
  21.  
  22. public IBaseDao<TMenu> getMenuDao() {
  23. return menuDao;
  24. }
  25.  
  26. @Autowired
  27. public void setMenuDao(IBaseDao<TMenu> menuDao) {
  28. this.menuDao = menuDao;
  29. }
  30.  
  31. @Override
  32. public List<Menu> getTreeNode(String id) {
  33. List<Menu> menus=new ArrayList<Menu>();
  34. StringBuffer hql=new StringBuffer();
  35. hql=hql.append("from TMenu t where ");
  36. Map<String, Object> map=new HashMap<String, Object>();
  37. if (id==null || "".equals(id)) {
  38. //返回总根节点
  39. hql=hql.append(" t.TMenu is null");
  40.  
  41. } else {
  42. //异步加载当前id下的子节点
  43. hql=hql.append(" t.TMenu.id=:id");
  44. map.put("id", id);
  45. }
  46. List<TMenu> tMenus= menuDao.find(hql.toString(),map);
  47. for (TMenu tMenu : tMenus) {
  48. Menu menu=new Menu();
  49. BeanUtils.copyProperties(tMenu, menu);
  50. Set<TMenu> set=tMenu.getTMenus();
  51. if (set!=null && !set.isEmpty()) {
  52. menu.setState("closed"); //节点以根节点形式体现(文件夹)
  53. } else {
  54. menu.setState("open"); //节点 以叶子形式体现(文件)
  55. }
  56. menus.add(menu);
  57. }
  58. return menus;
  59. }
  60.  
  61. }

  最后展示实现效果:当单击加号的时候才会加载其子节点,异步实现了功能树。

  

  下篇博客将介绍另一种加载树的方式,就是一次把所有的树节点都加载上来,显示扁平化数据。

  

EasyUI的功能树之异步树的更多相关文章

  1. EasyUI tree 异步树与采用扁平化实现的同步树

    所谓好记性不如烂笔头,为了以防忘记,才写下这篇博客,废话不多.. 异步树: tips:   可以采用easyui里的原始数据格式,也可以采用扁平化的数据格式. 使用场景: 当菜单模块数量庞大或者无限极 ...

  2. Easyui 异步树直接所有展开

    初始化异步树直接所有展开代码: $(function(){ $('#tt').tree({ url:'<%=request.getContextPath()%>/treeInit', li ...

  3. 蓝桥杯Web:【功能实现】菜单树检索

    [功能实现]菜单树检索 背景介绍 实际工作中很多前端攻城狮都会遇到这样一个需求:在多级菜单树中模糊搜索匹配的菜单项,并显示出来. 本题需要在已提供的基础项目中使用 Vue.js 知识,实现对已提供的二 ...

  4. zTree静态树与动态树的用法——(七)

    0.[简介] zTree 是利用 JQuery 的核心代码,实现一套能完成大部分常用功能的 Tree 插件 兼容 IE.FireFox.Chrome 等浏览器 在一个页面内可同时生成多个 Tree 实 ...

  5. 人人都是 DBA(VII)B 树和 B+ 树

    B 树(B-Tree)是为磁盘等辅助存取设备设计的一种平衡查找树,它实现了以 O(log n) 时间复杂度执行查找.顺序读取.插入和删除操作.由于 B 树和 B 树的变种在降低磁盘 I/O 操作次数方 ...

  6. 从B 树、B+ 树、B* 树谈到R 树

    从B 树.B+ 树.B* 树谈到R 树 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由 ...

  7. trie树(前缀树)

    问题描述:   Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优 ...

  8. 从B树、B+树、B*树谈到R 树

    从B 树.B+ 树.B* 树谈到R 树 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由 ...

  9. B-树、B+树、B*树的区别

      原文地址:  http://blog.csdn.net/dazhong159/article/details/7963846/ B-树.B+树.B*树的区别 2012-09-11 22:41 97 ...

随机推荐

  1. Orcale分析函数OVER(PARTITION BY... ORDER BY...)的讲解

    顾名思义,PARTITION 中文是分割的意思,ORDER 是排序的意思,所以翻译一下就是先把一组数据按照制定的字段进行分割成各种组,然后组内按照某个字段排序. 以实际案例来说明这个函数的使用, 首先 ...

  2. phpstorm设置断点过程

    1.为php安装xdebug,方法在上一篇中有详细介绍 2.注意这个时候需要修改php.ini内容如下: [Xdebug]zend_extension_ts ="d:/wamp/php/ex ...

  3. Flask简介,安装,demo,快速入门

    1.Flask简介 Flask是一个相对于Django而言轻量级的Web框架. 和Django大包大揽不同,Flask建立于一系列的开源软件包之上,这其中 最主要的是WSGI应用开发库Werkzeug ...

  4. 微服务之springCloud-docker-feign-hystrix(六)

    简介 上一节我们讨论feign的配置,这节我们讨论一下,feign+hystrix调用生产者时,进行容错处理 一.创建模块(microservice-consumer-movie-feign-with ...

  5. Ubuntu 12.04 LTS(64 bit) + RTL8188CU无线网卡驱动

    . . . . . 之前家里台式机上安装的是win7+CentOS双系统,但是CentOs的无线网卡驱动不知为何无论如何都安装不上,再加上这段时间一直很忙,所以一直使用着win.这几天事情忙得差不多了 ...

  6. Go Revel - Websockets

    revel提供了对`Websockets`的支持. 处理`Websockets`链接: 1.添加一个`WS`类型方法的路由 2.添加一个action接受 `*websocket.Conn`参数 例如, ...

  7. [转]Linux 命令行快捷键

    群里有人问"问个问题,Linux 命令行有没有快捷键一下从行末会到行头?经常敲了很多命令发现忘加 sudo 了,然后把命令删了重新敲一遍". 自己还真不知道怎么操作,只知道历史命令 ...

  8. Sahi (3) —— 压力测试Load Test以CAS SSO登陆场景为例(103 Tutorial)

    Sahi (3) -- 压力测试Load Test以CAS SSO登陆场景为例(103 Tutorial) jvm版本: 1.8.0_65 sahi版本: Sahi Pro 6.1.0 参考来源: S ...

  9. hive中窗口分析函数

    分组统计 1. groups sets(field1,field2,field3, (field1,field2)) 样例如下: select dt,tenantCode,nvl(platform,' ...

  10. 百度地图Api进阶教程-默认控件和自定义控件2.html

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="ini ...