




已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
利用多叉树实现Ext JS中的无限级树形菜单(一种构建多级有序树形结构JSON的方法)(版权所有:北京宇信易诚科技有限公司网上银行事业部)一、问题研究的背景和意义目前在Web应用程序开发领域,Ext JS框架已经逐渐被广泛使用,它是富客户端开发中出类拔萃的框架之一。在Ext的UI控件中,树形控件无疑是最为常用的控件之一,它用来实现树形结构的菜单。TreeNode用来实现静态的树形菜单,AsyncTreeNode用来实现动态的异步加载树形菜单,后者最为常用,它通过接收服务器端返回来的JSON格式的数据,动态生成树形菜单节点。动态生成树有两种思路:一种是一次性生成全部树节点,另一种是逐级加载树节点(利用AJAX,每次点击节点时查询下一级节点)。对于大数据量的菜单节点来说,逐级加载是比较合适的选择,但是对于小数据量的菜单来说,一次性生成全部节点应该是最为合理的方案。在实际应用开发中,一般不会遇到特别大数据量的场景,所以一次性生成全部菜单节点是我们重点研究的技术点,本文就是介绍基于Ext JS的应用系统中如何将数据库中的无限级层次数据一次性在界面中生成全部菜单节点(例如在界面中以树形方式一次性展示出银行所有分支机构的信息),同时对每一个层次的菜单节点按照某一属性和规则排序,展示出有序的菜单树。解决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字符串如图所示:我们给这棵树起个名字吧,就叫做multiple tree,简称M-Tree。三、源代码实现(Java语言版)实现这样一颗树,需要设计三个类:树类(ExtTree.java)、节点类(Node.java)、孩子列表类(Children.java);为了方便演示,还需要构造一些假的层次数据,因此还需要建一个构造假数据的类(VirtualDataGenerator.java),以下代码拷贝出来之后可直接运行测试:package test;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 ExtTree 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).children.addChild(node);/ 输出无序的树形菜单的JSON字符串System.out.println(root.toString();/ 对多叉树进行横向排序root.sortChildren();/ 输出有序的树形菜单的JSON字符串System.out.println(root.toString();/ 程序输出结果如下(无序的树形菜单)(格式化后的结果): /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;/* * 孩子节点列表 */public Children children = new Children();/ 先序遍历,拼接JSON字符串public String toString() String result = + id : + id + + , text : + text + ;if (children != null & children.getSize() != 0) result += , children : + children.toString(); else result += , leaf : true;return result + ;/ 兄弟节点横向排序public void sortChildren() if (children != null & children.getSize() != 0) children.sortChildren();/* 孩子列表类*/class Children public List list = new ArrayList();public int getSize() return list.size();public void addChild(Node node) list.add(node);/ 拼接孩子节点的JSON字符串public String toString() String result = ;for (Iterator it = list.iterator(); it.hasNext();) result += (Node) it.next().toString();result += ,;result = result.substring(0, result.length() - 1);result += ;return result;/ 孩子节点排序public void sortChildren() / 对本层节点进行排序/ 可根据不同的排序属性,传入不同的比较器,这里传入ID比较器Collections.sort(list, new NodeIDComparator();/ 对每个节点的下一层节点进行排序for (Iterator it = list.iterator(); it.hasNext();) (Node) it.next().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、 在不支持层次查询(hierarical retrival)的数据库应用系统中使用该算法实现相同的效果四、思考与总结这篇文章的重点是如何构造有序的无限级的树形结构JSON字符串,一次性生成树形菜单,而不是利用AJAX的方式,反复向服务器端发送请求,一级接一级的加载树节点。既然可以构造无限级的JSON字符串,那么也可以根据这个思路构造无限级的XML字符串,或者构
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年天成教育命题研究院高三物理第一学期期末检测试题
- 安徽省蚌埠市田家炳中学、五中2025年物理高三第一学期期末达标检测模拟试题
- 企业电力施工安全培训课件
- 澳洲超时出境管理办法
- 电子业务印章管理办法
- 煤矸石管理办法江西省
- 企业安全用电常识培训
- 出租车公司安全培训会议课件
- 2025服务器租用合同
- 出国务工安全教育培训课件
- 教育测量与评价 课件全套 朱德全 第1-15章 教育测量与评价概述- 教育测评结果的统计处理
- 技术文档编制管理规定
- 集成电路芯片测试技术PPT全套完整教学课件
- 法院送达地址确认书
- 合理低价法投标报价得分自动计算表
- 土地资源管理专业考试知识事业单位考试
- 《琵琶行》导学案-教师版
- GA/T 1968-2021法医学死亡原因分类及其鉴定指南
- 安全技术交底(蜘蛛人)
- 砼搅拌机、灰浆机验收记录表
- 1999年版干部履历表
评论
0/150
提交评论