看了“使用hibernate实现树形结构无限级分类”这篇文章后,我也想将自己在所有开发的项目中使用的功能模块树的实现方法以及完整DEMO(含源码)贴出来和大家分享。其实在我的博客里是老早贴出来的,由于时间关系没好好整理。

功能模块树是几乎在每个项目里都要用到的东西,利用Dojo的好处就是可以实现树的子节点的动态加载,这在树节点很多的情况下是很有用的。

下载附件二dojotree.rar,解压后将dist\dojotree.war部署到应用服务器即可浏览DEMO,DEMO中内置HSQLDB数据库,启动时自动加载。DEMO运行截图见附件一。


一、tree.jsp主要代码

1、首先在head中导入Dojo库(dojo.js)和TreeWidget

  1. <script type=< span="">"text/javascript" src="ajax/dojo/dojo.js">
  2. <script type=<span class="string">"text/javascript">
  3. dojo.require("dojo.widget.Tree");
  4. dojo.require("dojo.widget.TreeNode");
  5. dojo.require("dojo.widget.TreeSelector");
  6. dojo.require("dojo.widget.TreeRPCController");
  7. dojo.require("dojo.widget.TreeLoadingController");
  8. dojo.require("dojo.widget.TreeContextMenu");
  9. </script>

2、在body中放置TreeWidget,TreeLoadingController中的RPCUrl="treeServlet"为从后台获取数据的servlet名称,TreeNode中的expandLevel表示树初始张开级别

  1. <div dojoType="TreeLoadingController" RPCUrl="treeServlet" widgetId="treeController" DNDController="create">div>
  2. <div dojoType="TreeSelector" widgetId="treeSelector">div>
  3. <div dojoType="Tree" DNDMode="between" selector="treeSelector" widgetId="bandTree" controller="treeController">
  4. <div dojoType="TreeNode" title="root" widgetId="root" objectId="root" isFolder="true" childIconSrc="images/comm.gif" expandLevel="1"/>

3、建立TreeSelector事件处理函数

  1. function treeSelectFired() {
  2. // get a reference to the treeSelector and get the selected node
  3. var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');
  4. var treeNode = treeSelector.selectedNode;
  5. // get a reference to the songDisplay div
  6. var hostDiv = document.getElementById("songDisplay");
  7. var isFolder = treeNode['isFolder'];
  8. //alert(isFolder);
  9. if ( !isFolder) {
  10. var song = treeNode['title'];
  11. var url = treeNode['url'];
  12. link(url);
  13. } else {
  14. }
  15. }

4、将select事件处理函数关联到treeSelector

  1. function init() {
  2. //get a reference to the treeSelector
  3. var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');
  4. //connect the select event to the function treeSelectFired()
  5. dojo.event.connect(treeSelector,'select','treeSelectFired');
  6. }
  7. dojo.addOnLoad(init);

二、主要java代码及数据结构

1、Gnmk.java中tree的属性

  1. private String id;
  2. private String gnmkdm;  //功能模块代码
  3. private String gnmksm;  //功能模块说明
  4. private String gnmktb;  //功能模块图标
  5. private String gnmklj;  //功能模块路径
  6. private String gnmkmc;  //功能模块名称
  7. private String gnmksj;  //功能模块上级代码
  8. private String gnmkbz;  //功能模块标志(‘N’为叶节点)

2、HSQLDB内存数据库加载SQL(db.sql)

  1. CREATE TABLE GNMK (ID VARCHAR, GNMKDM VARCHAR, GNMKMC VARCHAR, GNMKLJ VARCHAR, GNMKTB VARCHAR, GNMKBZ VARCHAR, GNMKSJ VARCHAR);
  2. INSERT INTO GNMK VALUES ('d098a59f0b765c30010b765d6b780001', '01', '一级目录1', null, 'system.gif', 'Y', '');
  3. INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830001', '0101', '二级目录1', 'cxtjAction.do', 'system.gif', 'N', '01');
  4. INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830001', '0102', '二级目录2', 'cxtjAction.do', 'system.gif', 'N', '01');
  5. INSERT INTO GNMK VALUES ('d098a59f0b765c30010b765d6b780002', '02', '一级目录2', null, 'system.gif', 'Y', '');
  6. INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '0201', '二级目录1', 'cxtjAction.do', 'system.gif', 'N', '02');
  7. INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '0202', '二级目录2', 'cxtjAction.do', 'system.gif', 'Y', '02');
  8. INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '020201', '三级目录1', 'cxtjAction.do', 'system.gif', 'N', '0202');
  9. INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '020202', '三级目录2', 'cxtjAction.do', 'system.gif', 'N', '0202');

3、TreeServlet .java主要代码,在getGnmkByParent(String gnmksj)方法中可以实现自己的业务,DEMO中使用GnmkDAO

  1. public class TreeServlet extends HttpServlet {
  2. private static final long serialVersionUID = 1L;
  3. protected void doGet(HttpServletRequest request,
  4. HttpServletResponse response) throws ServletException, IOException {
  5. String action = request.getParameter("action");
  6. System.out.println("action b=>" + action);
  7. System.out.println("action b=>" + action);
  8. String data = request.getParameter("data");
  9. if (action.equalsIgnoreCase("getChildren")) {
  10. JSONTokener jsonTokener = new JSONTokener(data);
  11. JSONObject jsonObject = (JSONObject) jsonTokener.nextValue();
  12. JSONObject parentNodeObject = (JSONObject) jsonObject.get("node");
  13. response.setContentType("text/json; charset=gb2312");
  14. PrintWriter out = response.getWriter();
  15. out.write(getChildren(parentNodeObject));
  16. } else {
  17. }
  18. }
  19. private String getChildren(JSONObject parentNodeObject) {
  20. JSONArray result = new JSONArray();
  21. String parentObjectId = parentNodeObject.getString("objectId");// id 唯一
  22. // String parentWidgetId = parentNodeObject.getString("widgetId");// dm
  23. parentObjectId = parentObjectId.equalsIgnoreCase("root") ? ""
  24. : parentObjectId;
  25. System.out.println("parentObjectId=>" + parentObjectId);
  26. // 获取子功能模块
  27. List listGnmk = this.getGnmkByParent(parentObjectId);
  28. System.out.println("listGnmk=>" + listGnmk.size());
  29. if (listGnmk != null) {
  30. Iterator itGnmk = listGnmk.iterator();
  31. while (itGnmk.hasNext()) {
  32. Gnmk qxgnmk = (Gnmk) itGnmk.next();
  33. try {
  34. JSONObject jsonGnmkObject = new JSONObject();
  35. String gnmkbz = qxgnmk.getGnmkbz();
  36. boolean isFolder = gnmkbz.equalsIgnoreCase("Y") ? true
  37. : false;
  38. jsonGnmkObject.put("title", qxgnmk.getGnmkmc());
  39. jsonGnmkObject.put("isFolder", isFolder);
  40. jsonGnmkObject.put("widgetId", qxgnmk.getGnmkdm());
  41. jsonGnmkObject.put("objectId", qxgnmk.getGnmkdm());
  42. jsonGnmkObject.put("childIconSrc", "images/"
  43. + qxgnmk.getGnmktb());
  44. jsonGnmkObject.put("url", qxgnmk.getGnmklj());
  45. result.put(jsonGnmkObject);
  46. } catch (JSONException e) {
  47. e.printStackTrace();
  48. }
  49. }
  50. }
  51. return result.toString();
  52. }
  53. private List getGnmkByParent(String gnmksj) {
  54. GnmkDAO gnmkDao = new GnmkDAO();
  55. return gnmkDao.getGnmkByParent(gnmksj);
  56. }
  57. }

三、关于DEMO的其它配置说明

1、实现javax.servlet.ServletContextListener接口的contextInitialized方法来加载HSQLDB及其数据,ContextListener.java主要代码

  1. public void contextInitialized(ServletContextEvent event) {
  2. try {
  3. // load the driver
  4. Class.forName("org.hsqldb.jdbcDriver");
  5. // create the table and add sample data
  6. InputStreamReader in = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("db.sql"));
  7. BufferedReader reader = new BufferedReader(in);
  8. DBUtils.setupDatabase(reader);
  9. } catch (ClassNotFoundException e) {
  10. e.printStackTrace();
  11. }
  12. }

2、web.xml相关配置

  1. <listener>
  2. <listener-class>
  3. dojo.sample.ContextListener
  4. listener-class>
  5. >

  • 描述: DEMO截图
  • 大小: 8.5 KB
  • dojotree.rar (2.7 MB)
  • 描述: DEMO源代码
  • 下载次数: 9017
  • 查看图片附件

转载于:https://www.cnblogs.com/mylem/archive/2009/11/15/1603258.html

利用Dojo和JSON建立无限级AJAX动态加载的功能模块树相关推荐

  1. jquery table ajax,JQuery Ajax动态加载Table数据的实例讲解

    我们在jsp定义一个select和一个table,要求实现根据select的选值,动态加载table数据. table第一次加载数据的function定义如下: function loadData() ...

  2. html select ajax,AJAX 动态加载后台数据 绑定select的方法

    直接上代码 是可以用的,后台代码我就不贴了,我相信后台代码大家都会,直接返回json数据,我是前端比较差的,所以喜欢把每次不会的全部记起来 html代码 //下拉框数据动态加载 js代码 $.ajax ...

  3. Python爬取东方财富网任意股票任意时间段的Ajax动态加载股票数据

    导言 最近由于需求想爬取以下东方财富网的股票数据,但是发现没有想象那么简单,接下来我会讲述一下我遇到的问题以及是如何解决,最后成功的爬出了想要的数据. 查看网页源码 首先我们F12打开东方财富网网页源 ...

  4. python翻页功能url不变_爬取Ajax动态加载和翻页时url不变的网页

    这两天投了一家公司的爬虫实习生,笔试题是完成一个爬虫的小需求.网站没有什么反爬的高级技巧.但是有非常常见的,并不是针对我们爬虫的,却让我们新手很难理解的ajax动态加载技术和乍一看不明白的翻页时不变的 ...

  5. 关于使用scrapy框架编写爬虫以及Ajax动态加载问题、反爬问题解决方案

    关于使用scrapy框架编写爬虫以及Ajax动态加载问题.反爬问题解决方案 参考文章: (1)关于使用scrapy框架编写爬虫以及Ajax动态加载问题.反爬问题解决方案 (2)https://www. ...

  6. ajax 动态加载的内容,相应的js也要在回调里加载

    ajax 动态加载的内容,相应的js也要在回调里加载,不然之前已经写好的监听函数,其实没有绑定到后来动态加载的元素上的,所以要写成回调的形式比如: $(".getStudent") ...

  7. ajax动态拼接复选框样式,JavaScript 通过Ajax 动态加载CheckBox复选框

    废话不多说了,直接给大家贴代码了,具体代码如下所示: //动态加载年份checkbox by dongch 20170830 function GetCompareYearByStationName( ...

  8. python爬虫之Ajax动态加载数据抓取--豆瓣电影/腾讯招聘

    动态加载数据抓取-Ajax 特点 1.右键 -> 查看网页源码中没有具体数据 2.滚动鼠标滑轮或其他动作时加载 抓取 1.F12打开控制台,页面动作抓取网络数据包 2.抓取json文件URL地址 ...

  9. 爬取通过ajax动态加载的页面(实时监控华尔街见闻资讯与快讯)

    学习了几天如何使用scrapy去爬取静态网站,今天尝试去爬取动态加载的网站.选取的网站是华尔街见闻,文中不会像往常一样大篇幅讲解每一步该如何做,而是探讨如何爬取. 在源代码中无法获得全部数据(有的根本 ...

  10. ASP.NET 动态加载WebService功能

    在某些情况下,我们不能修改项目,重新引入一个WebService,然后再修改代码编译.所以最好解决办法是,通过一个小的dll,或者是cs文件,来实现动态加载webservice,这样现有项目,只需要在 ...

最新文章

  1. 余弦距离(Cosine距离)与编辑距离分别是什么?各有什么优势和使用场景?
  2. for each .. in ,for ... in , for ... of的用法
  3. FXK Javascript
  4. nao机器人拆解_一些机器人硬件网站
  5. [Intel Edison开发板] 02、Edison开发板入门
  6. 2021游戏市场风向标报告
  7. 关于mysql的一些问题
  8. 【kafka】kafka Offset commit failed on partition The coordinator is not aware of this member
  9. mac. mysql 设置root_Mac平台重新设置MySQL的root密码
  10. Mysql中,int(10)和int(11)的区别
  11. Qt qtextstream读取文件
  12. Android简易本地音乐播放器,Android简易音乐播放器实现代码
  13. 已解决:Connection timed out: connect. If you are behind an HTTP proxy, please configure the proxy
  14. CSS实现文字凹凸效果
  15. PTA L1-016 查验身份证(15分)
  16. mysql的安装使用(免安装版)
  17. 微信群裂变引流文案技巧,这样写文案更吸引粉丝!
  18. 2014年12月31日这一天,我想说明天会更好!
  19. C语言:输入某一年的第几天,计算并输出它是这一年的第几月第几日?
  20. Oracle 创建PDB的几种常用方法

热门文章

  1. jQuery CheckBoxList 全选 反选
  2. struts2通配符及Action开发的三种方式
  3. gridview怎么判断两行字符串是否相等_Python语言难学吗?第13讲——用数据做判断:布尔值...
  4. centos7从有线切换到无线_TT G821 W1无线三模机械键盘体验:一个键盘满足所有应用场景...
  5. hive设置为本地模式,从而避免MapReduce
  6. html 设置自动检测编码格式,CSS代码检查工具stylelint的使用方法详解
  7. PyCharm安装配置Django,启动第一个Django项目Hello World
  8. (day 49 - 另起数组牺牲空间换取时间 ) 剑指 Offer 66. 构建乘积数组
  9. python统计word页码_使用Python(win32com)在MS Word表中插入带页码的字段
  10. php 导入excal,php导入excel php使用phpexcel导入excel文件