多叉树结合JavaScript树形控件实现无限级树形菜单一种构建多级有序树形结构JSON或XML数据源的方法

上传人:痛*** 文档编号:89941233 上传时间:2022-05-13 格式:DOC 页数:12 大小:64.50KB
收藏 版权申诉 举报 下载
多叉树结合JavaScript树形控件实现无限级树形菜单一种构建多级有序树形结构JSON或XML数据源的方法_第1页
第1页 / 共12页
多叉树结合JavaScript树形控件实现无限级树形菜单一种构建多级有序树形结构JSON或XML数据源的方法_第2页
第2页 / 共12页
多叉树结合JavaScript树形控件实现无限级树形菜单一种构建多级有序树形结构JSON或XML数据源的方法_第3页
第3页 / 共12页
资源描述:

《多叉树结合JavaScript树形控件实现无限级树形菜单一种构建多级有序树形结构JSON或XML数据源的方法》由会员分享,可在线阅读,更多相关《多叉树结合JavaScript树形控件实现无限级树形菜单一种构建多级有序树形结构JSON或XML数据源的方法(12页珍藏版)》请在装配图网上搜索。

1、-多叉树结合JavaScript树形控件实现无限级树形菜单一种构建多级有序树形构造JSON或*ML数据源的方法一、问题研究的背景和意义在Web应用程序开发领域,基于AJA*技术的JavaScript树形控件已经被广泛使用,它用来在Html页面上展现具有层次构造的数据项。目前市场上常见的JavaScript框架及组件库中均包含自己的树形控件,例如JQuery、Dojo、 UI、E*t JS等,还有一些独立的树形控件,例如dhtml*tree等,这些树形控件完美的解决了层次数据的展示问题。展示离不开数据,树形控件主要利用AJA*技术从效劳器端获取数据源,数据源的格式主要包括JSON、*ML等,而这

2、些层次数据一般都存储在数据库中。“无限级树形菜单,顾名思义,没有级别的限制,它的数据通常来自数据库中的无限级层次数据,这种数据的存储表通常包括id和parentId这两个字段,以此来表示数据之间的层次关系。现在问题来了,既然树形控件的数据源采用JSON或*ML等格式的字符串来组织层次数据,而层次数据又存储在数据库的表中,则如何建立起树形控件与层次数据之间的关系,换句话说,如何将数据库中的层次数据转换成对应的层次构造的JSON或*ML格式的字符串,返回给客户端的JavaScript树形控件.这就是我们要解决的关键技术问题。本文将以目前市场上比较炽热的E*t JS框架为例,讲述实现无限级树形菜单的

3、方法,该方法同样适用于其它类似的JS树形控件。E*t JS框架是富客户端开发中出类拔萃的框架之一。在E*t的UI控件中,树形控件无疑是最为常用的控件之一,它用来实现树形构造的菜单。TreeNode用来实现静态的树形菜单,AsyncTreeNode用来实现动态的异步加载树形菜单,后者最为常用,它通过接收效劳器端返回来的JSON格式的数据,动态生成树形菜单节点。动态生成树有两种思路:一种是一次性生成全部树节点,另一种是逐级加载树节点利用AJA*,每次点击节点时查询下一级节点。对于大数据量的菜单节点来说,逐级加载是比较适宜的选择,但是对于小数据量的菜单来说,一次性生成全部节点应该是最为合理的方案。在

4、实际应用开发中,一般不会遇到特别大数据量的场景,所以一次性生成全部菜单节点是我们重点研究的技术点,也就是本文要解决的关键技术问题。本文以基于E*t JS的应用系统为例,讲述如何将数据库中的无限级层次数据一次性在界面中生成全部菜单节点例如在界面中以树形方式一次性展示出银行所有分支机构的信息,同时对每一个层次的菜单节点按照*一属性和规则排序,展示出有序的菜单树。解决一次性构造无限级树形菜单的问题,可以拓展出更多的应用场景,例如树形构造表格TreeGrid,一次性生成树形表格,对树形表格进展完整分页,对表格列进展全排序;或者可以利用本文的思路扩展出其他的更复杂的应用场景。先看两个图例,有个直观上的认

5、识:图一,银行分支机构树形构造菜单图二,树形构造表格二、详细设计方案让我们先看两段代码片段:文件一,branchTree.html E*t树形控件页面E*t.onReady(function() var tree = new E*t.tree.TreePanel( height: 300, width: 400, animate:true, enableDD:true,containerScroll: true, rootVisible: false, frame: true,/ getBranch.do请求效劳器返回多级树形构造的JSON字符串 loader: new E*t.tree.Tr

6、eeLoader(dataUrl:getBranch.do), root : new E*t.tree.AsyncTreeNode(id:0,te*t:根结点) ); tree.e*pandAll(); );文件二,branchTreeJSON.jsp 接收getBranch.do请求,返回多级树形构造的JSON字符串 以上两个程序文件是一次性生成无限级树形菜单所必须的,其中最为关键的局部就是如何生成一个无限级的树形构造JSON字符串,返回给客户端的E*t树形控件。对于银行分支机构来说,需要返回类似如下的JSON串:id : 100000, te*t : *银行总行, children : i

7、d : 110000, te*t : *分行, children : id : 113000, te*t : *银行开发区支行, leaf : true,id : 112000, te*t : *银行解放道支行, children : id : 112200, te*t : *银行三大街支行, leaf : true,id : 112100, te*t : *银行广阳道支行, leaf : true,id : 111000, te*t : *银行金光道支行, leaf : true同时还需要对树中每一个层次的节点按照*一属性比方分支机构编号进展排序,以展示出有序的树形菜单。现在可以把问题概括为

8、:1、 把数据库中的层次数据转换成多级树形构造的JSON格式的字符串2、 对树中每一个层次的节点按照*一属性比方分支机构编号进展排序下面介绍解决问题的思路:在数据构造这门课中,我们都学过树,无限级树形菜单就可以抽象成一种多叉树构造,即每个节点下包含多个子节点的树形构造,首先就需要把数据库中的层次数据转换成多叉树构造的对象树,也就是构造出一棵多叉树。有了数据构造,还要实现相应的算法,我们需要实现两种算法:1、兄弟节点横向排序算法,对隶属于同一个父节点下面的所有直接子节点按照*一节点属性和规则进展排序,保持兄弟节点横向有序;2、先序遍历算法,递归打印出无限级JSON字符串。概括起来分为三步:1、

9、构造无序的多叉树构造2、 实现兄弟节点横向排序方法3、 实现先序遍历方法,打印出JSON字符串如下列图:我们给这棵树起个名字吧,就叫做multiple tree,简称M-Tree。三、源代码实现Java语言版实现这样一颗树,需要设计三个类:树类MultipleTree.java、节点类Node.java、孩子列表类Children.java;为了方便演示,还需要构造一些假的层次数据,因此还需要建一个构造假数据的类VirtualDataGenerator.java,以下代码拷贝出来之后可直接运行测试:package test;import java.util.ArrayList;import j

10、ava.util.parator;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.Collections;/* * 多叉树类*/public class MultipleTree public static void main(String args) / 读取层次数据结果集列表 List dataList = VirtualDataGenerator.getVirtualResu

11、lt();/ 节点列表散列表,用于临时存储节点对象HashMap nodeList = new HashMap();/ 根节点Node root = null;/ 根据结果集构造节点列表存入散列表for (Iterator it = dataList.iterator(); it.hasNe*t();) Map dataRecord = (Map) it.ne*t();Node node = new Node();node.id = (String) dataRecord.get(id);node.te*t = (String) dataRecord.get(te*t);node.parent

12、Id = (String) dataRecord.get(parentId);nodeList.put(node.id, node);/ 构造无序的多叉树Set entrySet = nodeList.entrySet();for (Iterator it = entrySet.iterator(); it.hasNe*t();) Node node = (Node) (Map.Entry) it.ne*t().getValue();if (node.parentId = null | node.parentId.equals() root = node; else (Node) nodeLi

13、st.get(node.parentId).addChild(node);/ 输出无序的树形菜单的JSON字符串System.out.println(root.toString();/ 对多叉树进展横向排序root.sortChildren();/ 输出有序的树形菜单的JSON字符串System.out.println(root.toString();/ 程序输出结果如下无序的树形菜单格式化后的结果: /id : 100000, /te*t : *银行总行, /children : /id : 110000, /te*t : *分行, /children : /id : 113000, /te

14、*t : *银行开发区支行, /leaf : true/,/id : 111000, /te*t : *银行金光道支行, /leaf : true/,/id : 112000, /te*t : *银行解放道支行, /children : /id : 112200, /te*t : *银行三大街支行, /leaf : true/,/id : 112100, /te*t : *银行广阳道支行, /leaf : true/ 程序输出结果如下有序的树形菜单格式化后的结果:/id : 100000, /te*t : *银行总行, /children : /id : 110000, /te*t : *分行

15、, /children : /id : 111000, /te*t : *银行金光道支行, /leaf : true/,/id : 112000, /te*t : *银行解放道支行, /children : /id : 112100, /te*t : *银行广阳道支行, /leaf : true/,/id : 112200, /te*t : *银行三大街支行, /leaf : true/,/id : 113000, /te*t : *银行开发区支行, /leaf : true/* 节点类*/class Node /* * 节点编号 */public String id;/* * 节点内容 */

16、public String te*t;/* * 父节点编号 */public String parentId;/* * 孩子节点列表 */private Children children = new Children();/ 先序遍历,拼接JSON字符串public String toString() String result = + id : + id + + , te*t : + te*t + ;if (children != null & children.getSize() != 0) result += , children : + children.toString(); el

17、se result += , leaf : true;return result + ;/ 兄弟节点横向排序public void sortChildren() if (children != null & children.getSize() != 0) children.sortChildren();/ 添加孩子节点public void addChild(Node node) this.children.addChild(node);/* 孩子列表类*/class Children private List list = new ArrayList();public int getSiz

18、e() return list.size();public void addChild(Node node) list.add(node);/ 拼接孩子节点的JSON字符串public String toString() String result = ;for (Iterator it = list.iterator(); it.hasNe*t();) result += (Node) it.ne*t().toString();result += ,;result = result.substring(0, result.length() - 1);result += ;return res

19、ult;/ 孩子节点排序public void sortChildren() / 对本层节点进展排序/ 可根据不同的排序属性,传入不同的比较器,这里传入ID比较器Collections.sort(list, new NodeIDparator();/ 对每个节点的下一层节点进展排序for (Iterator it = list.iterator(); it.hasNe*t();) (Node) it.ne*t().sortChildren();/* * 节点比较器 */class NodeIDparator implements parator / 按照节点编号比较public int par

20、e(Object o1, Object o2) int j1 = Integer.parseInt(Node)o1).id); int j2 = Integer.parseInt(Node)o2).id);return (j1 j2 ? -1 : (j1 = j2 ? 0 : 1);/* * 构造虚拟的层次数据 */class VirtualDataGenerator / 构造无序的结果集列表,实际应用中,该数据应该从数据库中查询获得;public static List getVirtualResult() List dataList = new ArrayList();HashMap da

21、taRecord1 = new HashMap();dataRecord1.put(id, 112000);dataRecord1.put(te*t, *银行解放道支行);dataRecord1.put(parentId, 110000);HashMap dataRecord2 = new HashMap();dataRecord2.put(id, 112200);dataRecord2.put(te*t, *银行三大街支行);dataRecord2.put(parentId, 112000);HashMap dataRecord3 = new HashMap();dataRecord3.pu

22、t(id, 112100);dataRecord3.put(te*t, *银行广阳道支行);dataRecord3.put(parentId, 112000);HashMap dataRecord4 = new HashMap();dataRecord4.put(id, 113000);dataRecord4.put(te*t, *银行开发区支行);dataRecord4.put(parentId, 110000);HashMap dataRecord5 = new HashMap();dataRecord5.put(id, 100000);dataRecord5.put(te*t, *银行总

23、行);dataRecord5.put(parentId, );HashMap dataRecord6 = new HashMap();dataRecord6.put(id, 110000);dataRecord6.put(te*t, *分行);dataRecord6.put(parentId, 100000);HashMap dataRecord7 = new HashMap();dataRecord7.put(id, 111000);dataRecord7.put(te*t, *银行金光道支行);dataRecord7.put(parentId, 110000);dataList.add(d

24、ataRecord1);dataList.add(dataRecord2);dataList.add(dataRecord3);dataList.add(dataRecord4);dataList.add(dataRecord5);dataList.add(dataRecord6);dataList.add(dataRecord7);return dataList;好了,通过上面的代码,就可以实现多叉树的兄弟节点横向排序和先序遍历了,实现了将层次数据转换为有序无限级树形构造JSON字符串的目的。在实际的工程中,可以把上面的有效代码融入其中,或者在此根底上进展一些扩展:1、 实现对指定层次的排序

25、例如只排序第一层的节点,或者只排序*一父节点下的所有子节点2、 遍历输出树形构造时可以参加判断条件过滤掉*些节点3、 实现节点的删除功能4、 在节点类中增加一个父节点的引用,就可以计算出*一节点所处的级别5、 在不支持层次查询hierarical retrival的数据库应用系统中使用该算法实现一样的效果四、思考与总结这篇文章的重点是如何构造有序的无限级的树形构造JSON字符串,一次性生成树形菜单,而不是利用AJA*的方式,反复向效劳器端发送请求,一级接一级的加载树节点。既然可以构造无限级的JSON字符串,则也可以根据这个思路构造无限级的*ML字符串,或者构造具有层次构造的UL LI组合用UL

26、 - LI来展示树形构造,或者构造具有层次构造的TABLE用TABLE来展示树形构造。如下所示:1*ML层次构造2UL - LI 层次构造*银行总行*分行 *银行开发区支行 *银行解放道支行 *银行三大街支行 *银行广阳道支行 *银行金光道支行3TABLE层次构造*银行总行  *分行    *银行开发区支行    *银行解放道支行      *银行三大街支行      *银行广

27、阳道支行    *银行金光道支行另外对TreeGrid树形表格也有一定的价值:1、 一次性构造树形表格,实现数据分级展示2、 通过更换比较器,实现对不同表格列的全排序全排序指的是对所有页的数据进展排序,而不是只对当前页的数据排序3、 实现对树形表格的完整分页每次分页时,只取固定数目的第一层节点,之后调用toString方法,展示出完整条数的分级数据五、参考书籍1、Mark Allen Weiss,数据构造与算法分析Java语言描述2、Bruce Eckel,Thinking In Java Third Edition3、DavidFlanagan,Jav

28、aScript: The Definitive Guide, 5th Edition4、OCA Oracle Database 11g SQL Fundamentals I E*am Guide5、侯捷,重构-改善既有代码的设计注:本文的思路方法是是受到Oracle层次查询的启发,所以将?OCA Oracle Database 11g SQL Fundamentals I E*am Guide?这本书也写在了参考书籍里面,以表示对Oracle的感谢。构造多叉树的方法是从数据构造中获得灵感,故也把?数据构造与算法分析Java语言描述?这本书列了出来,以示感谢。六、联系方式memorymultitree163. z

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!