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

  

 $.fn.tree.defaults.loadFilter = function (data, parent) {
var opt = $(this).data().tree.options;
var idFiled,
textFiled,
parentField;
if (opt.parentField) {
idFiled = opt.idFiled || 'id';
textFiled = opt.textFiled || 'text';
parentField = opt.parentField; var i,
l,
treeData = [],
tmpMap = []; for (i = 0, l = data.length; i < l; i++) {
tmpMap[data[i][idFiled]] = data[i];
} for (i = 0, l = data.length; i < l; i++) {
if (tmpMap[data[i][parentField]] && data[i][idFiled] != data[i][parentField]) {
if (!tmpMap[data[i][parentField]]['children'])
tmpMap[data[i][parentField]]['children'] = [];
data[i]['text'] = data[i][textFiled];
tmpMap[data[i][parentField]]['children'].push(data[i]);
} else {
data[i]['text'] = data[i][textFiled];
treeData.push(data[i]);
}
}
return treeData;
}
return data;
};

  2、Action类实现

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

  

 import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table; /**
* TMenu entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "t_menu", catalog = "easyui")
public class TMenu implements java.io.Serializable { // Fields private String id;
private TMenu TMenu;
private String text;
private String iconCls;
private String url;
private Set<TMenu> TMenus = new HashSet<TMenu>(0); // Constructors /** default constructor */
public TMenu() {
} /** minimal constructor */
public TMenu(String id) {
this.id = id;
} /** full constructor */
public TMenu(String id, TMenu TMenu, String text, String iconCls, String url, Set<TMenu> TMenus) {
this.id = id;
this.TMenu = TMenu;
this.text = text;
this.iconCls = iconCls;
this.url = url;
this.TMenus = TMenus;
} // Property accessors
@Id
@Column(name = "id", unique = true, nullable = false, length = 36)
public String getId() {
return this.id;
} public void setId(String id) {
this.id = id;
} @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "pid")
public TMenu getTMenu() {
return this.TMenu;
} public void setTMenu(TMenu TMenu) {
this.TMenu = TMenu;
} @Column(name = "text", length = 100)
public String getText() {
return this.text;
} public void setText(String text) {
this.text = text;
} @Column(name = "iconCls", length = 50)
public String getIconCls() {
return this.iconCls;
} public void setIconCls(String iconCls) {
this.iconCls = iconCls;
} @Column(name = "url", length = 200)
public String getUrl() {
return this.url;
} public void setUrl(String url) {
this.url = url;
} @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "TMenu")
public Set<TMenu> getTMenus() {
return this.TMenus;
} public void setTMenus(Set<TMenu> TMenus) {
this.TMenus = TMenus;
} }

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

  

 public class Menu {

     private String pid;//父菜单ID
private String pText;//父菜单名称
private String id;//子菜单Id
private String text;//子菜单名称
private String iconCls;//子菜单图标
private String url;//子菜单路径
private String state; //---------------set/get-------------- public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
} public String getpText() {
return pText;
}
public void setpText(String pText) {
this.pText = pText;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
} public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getIconCls() {
return iconCls;
}
public void setIconCls(String iconCls) {
this.iconCls = iconCls;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
} }

  

  Action类:

  

 package com.action;

 import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.springframework.beans.factory.annotation.Autowired; import com.pageModel.Menu;
import com.service.IMenuService; import com.opensymphony.xwork2.ModelDriven; @ParentPackage("basePackage")
@Namespace("/")
@Action(value="menuAction")
public class MenuAction extends BaseAction implements ModelDriven<Menu> {
Menu menu=new Menu();
@Override
public Menu getModel() {
// TODO Auto-generated method stub
return menu;
}
private IMenuService menuService; public IMenuService getMenuService() {
return menuService;
}
@Autowired
public void setMenuService(IMenuService menuService) {
this.menuService = menuService;
}
/**
* 异步获得树节点
*/
public void getTreeNode(){
super.writeJson(menuService.getTreeNode(menu.getId()));
}
}

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

  对应service的实现类:

 package com.service.impl;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.dao.IBaseDao;
import com.model.TMenu;
import com.pageModel.Menu;
import com.service.IMenuService; @Service("menuService")
public class MenuServiceImpl implements IMenuService {
private IBaseDao<TMenu> menuDao; public IBaseDao<TMenu> getMenuDao() {
return menuDao;
} @Autowired
public void setMenuDao(IBaseDao<TMenu> menuDao) {
this.menuDao = menuDao;
} @Override
public List<Menu> getTreeNode(String id) {
List<Menu> menus=new ArrayList<Menu>();
StringBuffer hql=new StringBuffer();
hql=hql.append("from TMenu t where ");
Map<String, Object> map=new HashMap<String, Object>();
if (id==null || "".equals(id)) {
//返回总根节点
hql=hql.append(" t.TMenu is null"); } else {
//异步加载当前id下的子节点
hql=hql.append(" t.TMenu.id=:id");
map.put("id", id);
}
List<TMenu> tMenus= menuDao.find(hql.toString(),map);
for (TMenu tMenu : tMenus) {
Menu menu=new Menu();
BeanUtils.copyProperties(tMenu, menu);
Set<TMenu> set=tMenu.getTMenus();
if (set!=null && !set.isEmpty()) {
menu.setState("closed"); //节点以根节点形式体现(文件夹)
} else {
menu.setState("open"); //节点 以叶子形式体现(文件)
}
menus.add(menu);
}
return menus;
} }

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

  

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

  

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. java基础篇---异常处理

    认识异常 异常时导致程序中断运行的一种指令流,如果不对异常进行正确的处理,则可能导致程序的中断执行,造成不必要的损失,所以在程序的设计中必须考虑各种异常的发生,并正确的做好相应的处理,这样才能保证程序 ...

  2. Java多线程——sychronized

    概述 关键字synchronized的作用是实现线程间的同步.它的工作是对同步的代码加锁,使得每一次,只能有一个线程进入同步块,从而保证线程间的安全性. 直接作用于实例方法(普通同步方法):对当前实例 ...

  3. [wdt]watchdog

    board/ti/am335x/board.c board/ti/am43xx/board.c driver/watchdog/omap_wdt.c include/configs/am43xx_ev ...

  4. PHP——大话PHP设计模式——命名空间和类的自动载入

    开发工具:phpstorm phpstudy 命名空间:声明当前文件 类的自动载入

  5. c# dump 程序崩溃 windbg

    待研究 http://issf.blog.163.com/blog/static/194129082201002534895/ http://www.cppblog.com/woaidongmao/a ...

  6. Android训练课程(Android Training) - 添加活动栏(使用action bar)

    2014-10-28 张云飞VIR 翻译自:https://developer.android.com/training/basics/actionbar/index.html 添加活动栏(Addin ...

  7. SpringCloud 详解配置刷新的原理 使用jasypt自动加解密后 无法使用 springcloud 中的自动刷新/refresh功能

    之所以会查找这篇文章,是因为要解决这样一个问题: 当我使用了jasypt进行配置文件加解密后,如果再使用refresh 去刷新配置,则自动加解密会失效. 原因分析:刷新不是我之前想象的直接调用conf ...

  8. C#里的SubString和Convert.ToDateTime

    1.C#里的SubString String.SubString(int   index,int   length) index:开始位置,从0开始 length:你要取的子字符串的长度 2.C#语言 ...

  9. Python 类的多态

    #python的多态 class Dog(): def eat(self): print("i am dog , eat something . ") class Cat(): d ...

  10. 查看和调试Qt源码

    简述 在调试程序的时候,有时需要调试进入 Qt 源码,这不仅有利于我们了解内部实现机制,而且对于解决一些隐蔽性问题很有帮助. 都知道 F11 是“单步进入”,可是在调试的过程中,按下 F11 却无法进 ...