EasyUI的功能树之异步树

  最近几个项目都用到了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的树控件:

<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
59 }

  

  Action类:

  

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

  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
23     public IBaseDao<TMenu> getMenuDao() {
24         return menuDao;
25     }
26
27     @Autowired
28     public void setMenuDao(IBaseDao<TMenu> menuDao) {
29         this.menuDao = menuDao;
30     }
31
32
33     @Override
34     public List<Menu> getTreeNode(String id) {
35         List<Menu> menus=new ArrayList<Menu>();
36         StringBuffer hql=new StringBuffer();
37         hql=hql.append("from TMenu t where  ");
38         Map<String, Object> map=new HashMap<String, Object>();
39         if (id==null || "".equals(id)) {
40             //返回总根节点
41             hql=hql.append(" t.TMenu is null");
42
43         } else {
44             //异步加载当前id下的子节点
45             hql=hql.append(" t.TMenu.id=:id");
46             map.put("id", id);
47         }
48         List<TMenu> tMenus= menuDao.find(hql.toString(),map);
49         for (TMenu tMenu : tMenus) {
50             Menu menu=new Menu();
51             BeanUtils.copyProperties(tMenu, menu);
52             Set<TMenu> set=tMenu.getTMenus();
53             if (set!=null && !set.isEmpty()) {
54                 menu.setState("closed");  //节点以根节点形式体现(文件夹)
55             } else {
56                 menu.setState("open");    //节点 以叶子形式体现(文件)
57             }
58             menus.add(menu);
59         }
60         return menus;
61     }
62
63 }

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

  

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

  

EasyUI的功能树之异步树

时间: 2024-10-10 00:56:06

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

easyUi在后台加载异步树

DAO就不写接口了,直接写实现类 public List<Dept> tree(String hql, String par) { Session session = getHibernateTemplate().getSessionFactory() .getCurrentSession(); List list = new ArrayList(); if (par.length() == 0) { list = session.createQuery(hql).list(); } else

Easyui 异步树直接全部展开

初始化异步树直接全部展开代码: $(function(){ $('#tt').tree({ url:'<%=request.getContextPath()%>/treeInit', lines:true, onLoadSuccess:function(node,data){ var t = $(this); if(data){ $(data).each(function(index,d){ if(this.state == 'closed'){ t.tree('expandAll'); }

Easyui 异步树直接所有展开

初始化异步树直接所有展开代码: $(function(){ $('#tt').tree({ url:'<%=request.getContextPath()%>/treeInit', lines:true, onLoadSuccess:function(node,data){ var t = $(this); if(data){ $(data).each(function(index,d){ if(this.state == 'closed'){ t.tree('expandAll'); }

EasyUI删除功能

EasyUI中的删除很简单,一般直接复制粘贴就行. 下面是对树节点的删除. // 删除 function removes() {     var rows = ruletreegrid.treegrid('getSelections');     if (rows && rows.length == 1) {         var showmsg = "";         if (rows[0].pid == 0) {             // 下面有子节点  

跳跃表,字典树(单词查找树,Trie树),后缀树,KMP算法,AC 自动机相关算法原理详细汇总

第一部分:跳跃表 本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈"跳跃表"的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢. 跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类

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

第一节.B树.B+树.B*树 1.前言: 动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree),红黑树(Red-Black Tree ),B-tree/B+-tree/ B*-tree(B~Tree).前三者是典型的二叉查找树结构,其查找的时间复杂度O(log2N)与树的深度相关,那么降低树的深度自然会提高查找效率. 但是咱们有面对这样一个实际问题:就是大规模数据存储中,实现索引查询这样一个实际背景下,树节

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

如图所示,区别有以下两点: 1. B+树中只有叶子节点会带有指向记录的指针(ROWID),而B树则所有节点都带有,在内部节点出现的索引项不会再出现在叶子节点中. 2. B+树中所有叶子节点都是通过指针连接在一起,而B树不会. B+树的优点: 1. 非叶子节点不会带上ROWID,这样,一个块中可以容纳更多的索引项,一是可以降低树的高度.二是一个内部节点可以定位更多的叶子节点. 2. 叶子节点之间通过指针来连接,范围扫描将十分简单,而对于B树来说,则需要在叶子节点和内部节点不停的往返移动. B树的优

B树、Trie树详解

查找(二) 散列表 散列表是普通数组概念的推广.由于对普通数组可以直接寻址,使得能在O(1)时间内访问数组中的任意位置.在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标. 使用散列的查找算法分为两步.第一步是用散列函数将被查找的键转化为数组的一个索引. 我们需要面对两个或多个键都会散列到相同的索引值的情况.因此,第二步就是一个处理碰撞冲突的过程,由两种经典解决碰撞的方法:拉链法和线性探测法. 散列表是算法在时间和空间上作出权衡的经典例子. 如果没有内存限制,我们可以直接

hiho #1014 : Trie树 (字典树的建立和查找)

#1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题:"小Ho,你能不能对于每一个我给出的字符串,都在这个词典里面找到以这个字符串开头的所有单词呢?" 身经百战的小Ho答道:"怎么会不能呢!你每给我一个字符串,我就依次遍历词典里的所有