多叉树结合JavaScript树形控件实现无限级树形结构(一种构建多级有序树形结构JSON(或XML)数据源的方法).doc_第1页
多叉树结合JavaScript树形控件实现无限级树形结构(一种构建多级有序树形结构JSON(或XML)数据源的方法).doc_第2页
多叉树结合JavaScript树形控件实现无限级树形结构(一种构建多级有序树形结构JSON(或XML)数据源的方法).doc_第3页
多叉树结合JavaScript树形控件实现无限级树形结构(一种构建多级有序树形结构JSON(或XML)数据源的方法).doc_第4页
多叉树结合JavaScript树形控件实现无限级树形结构(一种构建多级有序树形结构JSON(或XML)数据源的方法).doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北京交通大学 计算机系 硕士论文(2012年)多叉树结合JavaScript树形控件实现无限级树形结构(一种构建多级有序树形结构JSON(或XML)数据源的方法)一、问题研究的背景和意义在Web应用程序开发领域,基于Ajax技术的JavaScript树形控件已经被广泛使用,它用来在Html页面上展现具有层次结构的数据项。目前市场上常见的JavaScript框架及组件库中均包含自己的树形控件,例如jQuery、Dojo、YUI、Ext JS等,还有一些独立的树形控件,例如dhtmlxTree等,这些树形控件完美的解决了层次数据的展示问题。展示离不开数据,树形控件主要利用Ajax技术从服务器端获取数据源,数据源的格式主要包括JSON、XML等,而这些层次数据一般都存储在数据库中。“无限级树形结构”,顾名思义,没有级别的限制,它的数据通常来自数据库中的无限级层次数据,这种数据的存储表通常包括id和parentId这两个字段,以此来表示数据之间的层次关系。现在问题来了,既然树形控件的数据源采用JSON或XML等格式的字符串来组织层次数据,而层次数据又存储在数据库的表中,那么如何建立起树形控件与层次数据之间的关系,换句话说,如何将数据库中的层次数据转换成对应的层次结构的JSON或XML格式的字符串,返回给客户端的JavaScript树形控件?这就是我们要解决的关键技术问题。本文将以目前市场上比较知名的Ext JS框架为例,讲述实现无限级树形结构的方法,该方法同样适用于其它类似的JavaScript树形控件。Ext JS框架是富客户端开发中出类拔萃的框架之一。在Ext的UI控件中,树形控件无疑是最为常用的控件之一,它用来实现树形结构的视图。TreeNode用来实现静态的树形结构,AsyncTreeNode用来实现动态的异步加载树形结构,后者最为常用,它通过接收服务器端返回来的JSON格式的数据,动态生成树形结构节点。动态生成树有两种思路:一种是一次性生成全部树节点,另一种是逐级加载树节点(利用Ajax,每次点击节点时查询下一级节点)。对于大数据量的树节点来说,逐级加载是比较合适的选择,但是对于小数据量的树节点来说,一次性生成全部节点应该是最为合理的方案。在实际应用开发中,一般不会遇到特别大数据量的场景,所以一次性生成全部树节点是我们重点研究的技术点,也就是本文要解决的关键技术问题。本文以基于Ext JS的应用系统为例,讲述如何将数据库中的无限级层次数据一次性在界面中生成全部树节点(例如在界面中以树形方式一次性展示出银行所有分支机构的信息),同时对每一个层次的节点按照某一属性和规则排序,展示出有序的树形结构。解决一次性构造无限级树形结构的问题,可以拓展出更多的应用场景,例如树形结构表格TreeGrid,一次性生成树形表格,对树形表格进行完整分页,对表格列进行全排序;或者可以利用本文的思路扩展出其他的更复杂的应用场景。先看两个图例,有个直观上的认识:图一,银行分支机构树形结构图二,树形结构表格二、详细设计方案让我们先看两段代码片段:文件一,branchTree.html (Ext树形控件页面)Ext.onReady(function() var tree = new Ext.tree.TreePanel( height: 300, width: 400, animate:true, enableDD:true, containerScroll: true, rootVisible: false, frame: true,/ getBranch.do请求服务器返回多级树形结构的JSON字符串 loader: new Ext.tree.TreeLoader(dataUrl:getBranch.do), root : new Ext.tree.AsyncTreeNode(id:0,text:根结点) ); tree.expandAll(); );文件二,branchTreeJSON.jsp (接收getBranch.do请求,返回多级树形结构的JSON字符串) 以上两个程序文件是一次性生成无限级树形结构所必须的,其中最为关键的部分就是如何生成一个无限级的树形结构JSON字符串,返回给客户端的Ext树形控件。对于银行分支机构来说,需要返回类似如下的JSON串: id: 100000, text: 廊坊银行总行, children: id: 110000, text: 廊坊分行, children: id: 113000, text: 廊坊银行开发区支行, leaf: true , id: 112000, text: 廊坊银行解放道支行, children: id: 112200, text: 廊坊银行三大街支行, leaf: true , id: 112100, text: 廊坊银行广阳道支行, leaf: true , id: 111000, text: 廊坊银行金光道支行, leaf: true 同时还需要对树中每一个层次的节点按照某一属性(比如分支机构编号)进行排序,以展示出有序的树形结构。现在可以把问题概括为:1、 把数据库中的层次数据转换成多级树形结构的JSON格式的字符串2、 对树中每一个层次的节点按照某一属性(比如分支机构编号)进行排序下面介绍解决问题的思路:在数据结构这门课中,我们都学过树,无限级树形结构就可以抽象成一种多叉树结构,即每个节点下包含多个子节点的树形结构,首先就需要把数据库中的层次数据转换成多叉树结构的对象树,也就是构造出一棵多叉树。有了数据结构,还要实现相应的算法,我们需要实现两种算法:1、兄弟节点横向排序算法,对隶属于同一个父节点下面的所有直接子节点按照某一节点属性和规则进行排序,保持兄弟节点横向有序;2、先序遍历算法,递归打印出无限级JSON字符串。概括起来分为三步:1、 构造无序的多叉树结构2、 实现兄弟节点横向排序方法3、 实现先序遍历方法,打印出JSON字符串如图所示:三、源代码实现(Java语言版)实现这样一颗树,需要设计两个类:树类(MultipleTree)、节点类(Node);排序时还需要一个比较器类(NodeIDComparator);为了方便演示,还需要构造一些假的层次数据,因此还需要建一个构造假数据的类(VirtualDataGenerator),以下代码拷贝出来之后可直接运行测试:package tree;import java.util.ArrayList;import java.util.Comparator;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.getVirtualResult();/ 节点列表(映射表,用于临时存储节点对象)HashMap nodeList = new HashMap();/ 根节点Node root = null;/ 将结果集存入映射表(后面将借助映射表构造多叉树)for (Iterator it = dataList.iterator(); it.hasNext();) Map dataRecord = (Map) it.next();Node node = new Node();node.id = (String) dataRecord.get(id);node.text = (String) dataRecord.get(text);node.parentId = (String) dataRecord.get(parentId);nodeList.put(node.id, node);/ 构造无序的多叉树Set entrySet = nodeList.entrySet();for (Iterator it = entrySet.iterator(); it.hasNext();) Node node = (Node) (Map.Entry) it.next().getValue();if (node.parentId = null | node.parentId.equals() root = node; else (Node) nodeList.get(node.parentId).addChild(node);/ 输出无序的树形结构的JSON字符串System.out.println(root);/ 对多叉树进行横向排序root.sortChildren();/ 输出有序的树形结构的JSON字符串System.out.println(root);/ 程序输出结果如下:/ 无序的树形结构(格式化后的结果,可使用JSON格式化工具查看,例如 http:/jsonviewer.stack.hu/ 在线查看器): / / id : 100000, / text : 廊坊银行总行, / children : / / id : 110000, / text : 廊坊分行, / children : / / id : 113000, / text : 廊坊银行开发区支行, / leaf : true/ ,/ / id : 111000, / text : 廊坊银行金光道支行, / leaf : true/ ,/ / id : 112000, / text : 廊坊银行解放道支行, / children : / / id : 112200, / text : 廊坊银行三大街支行, / leaf : true/ ,/ / id : 112100, / text : 廊坊银行广阳道支行, / leaf : true/ / / / / / / / 有序的树形结构(格式化后的结果):/ / id : 100000, / text : 廊坊银行总行, / children : / / id : 110000, / text : 廊坊分行, / children : / / id : 111000, / text : 廊坊银行金光道支行, / leaf : true/ ,/ / id : 112000, / text : 廊坊银行解放道支行, / children : / / id : 112100, / text : 廊坊银行广阳道支行, / leaf : true/ ,/ / id : 112200, / text : 廊坊银行三大街支行, / leaf : true/ / / ,/ / id : 113000, / text : 廊坊银行开发区支行, / leaf : true/ / / / / /* * 节点类 */class Node /* * 节点编号 */public String id;/* * 节点内容 */public String text;/* * 父节点编号 */public String parentId;/* * 孩子节点列表 */private List children = new ArrayList();/ 添加孩子节点public void addChild(Node node) children.add(node);/ 先序遍历,拼接JSON字符串public String toString() String result = + id : + id + + , text : + text + ;if (children.size() != 0) result += , children : ;for (int i = 0; i children.size(); i+) result += (Node) children.get(i).toString() + ,;result = result.substring(0, result.length() - 1);result += ; else result += , leaf : true;return result + ;/ 兄弟节点横向排序public void sortChildren() if (children.size() != 0) / 对本层节点进行排序(可根据不同的排序属性,传入不同的比较器,这里 传入ID比较器)Collections.sort(children, new NodeIDComparator();/ 对每个节点的下一层节点进行排序for (int i = 0; i children.size(); i+) (Node) children.get(i).sortChildren();/* * 节点比较器 */class NodeIDComparator implements Comparator / 按照节点编号比较public int compare(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 dataRecord1 = new HashMap();dataRecord1.put(id, 112000);dataRecord1.put(text, 廊坊银行解放道支行);dataRecord1.put(parentId, 110000);HashMap dataRecord2 = new HashMap();dataRecord2.put(id, 112200);dataRecord2.put(text, 廊坊银行三大街支行);dataRecord2.put(parentId, 112000);HashMap dataRecord3 = new HashMap();dataRecord3.put(id, 112100);dataRecord3.put(text, 廊坊银行广阳道支行);dataRecord3.put(parentId, 112000);HashMap dataRecord4 = new HashMap();dataRecord4.put(id, 113000);dataRecord4.put(text, 廊坊银行开发区支行);dataRecord4.put(parentId, 110000);HashMap dataRecord5 = new HashMap();dataRecord5.put(id, 100000);dataRecord5.put(text, 廊坊银行总行);dataRecord5.put(parentId, );HashMap dataRecord6 = new HashMap();dataRecord6.put(id, 110000);dataRecord6.put(text, 廊坊分行);dataRecord6.put(parentId, 100000);HashMap dataRecord7 = new HashMap();dataRecord7.put(id, 111000);dataRecord7.put(text, 廊坊银行金光道支行);dataRecord7.put(parentId, 110000);dataList.add(dataRecord1);dataList.add(dataRecord2);dataList.add(dataRecord3);dataList.add(dataRecord4);dataList.add(dataRecord5);dataList.add(dataRecord6);dataList.add(dataRecord7);return dataList;好了,通过上面的代码,就可以实现多叉树的兄弟节点横向排序和先序遍历了,实现了将层次数据转换为有序无限级树形结构JSON字符串的目的。在实际的项目中,可以把上面的有效代码融入其中,或者在此基础上进行一些扩展:1、 实现对指定层次的排序(例如只排序第一层的节点,或者只排序某一父节点下的所有子节点)2、 遍历输出树形结构时可以加入判断条件过滤掉某些节点3、 实现节点的删除功能4、 在节点类中增加一个父节点的引用,就可以计算出某一节点所处的级别5、 在不支持层次查询的数据库应用系统中使用该算法实现相同的效果四、思考与总结这篇文章的重点是如何构造有序的无限级的树形结构JSON字符串,一次性生成树形结构,而不是利用Ajax的方式,反复向服务器端发送请求,一级接一级的加载树节点。既然可以构造无限级的JSON字符串,那么也可以根据这个思路构造无限级的XML字符串,或者构造具有层次结构的UL LI组合(用UL - LI来展示树形结构),或者构造具有层次结构的TABLE(用TABLE来展示树形结构)。如下所示:(1)XML层次结构(2)UL - LI 层次结构廊坊银行总行廊坊分行 廊坊银行开发区支行 廊坊银行解放道支行 廊坊银行三大街支行 廊坊银行广阳道支行 廊坊银行金光道支行(3)TABLE层次结构廊坊银行总行  廊坊分行    廊坊银行开发区支行    廊坊银行解放道支行 &n

温馨提示

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

评论

0/150

提交评论