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 }

 

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

  

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

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM