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


Posted in Javascript onMarch 24, 2007

 看了“使用hibernate实现树形结构无限级分类”这篇文章后,我也想将自己在所有开发的项目中使用的功能模块树的实现方法以及完整DEMO(含源码)贴出来和大家分享。其实在我的博客里是老早贴出来的,由于时间关系没好好整理。
       功能模块树是几乎在每个项目里都要用到的东西,利用Dojo的好处就是可以实现树的子节点的动态加载,这在树节点很多的情况下是很有用的。
        下载附件二dojotree.rar,解压后将dist\dojotree.war部署到应用服务器即可浏览DEMO,DEMO中内置HSQLDB数据库,启动时自动加载。DEMO运行截图见附件一。 
一、tree.jsp主要代码
1、首先在head中导入Dojo库(dojo.js)和TreeWidget
<script>"text/javascript" src="ajax/dojo/dojo.js">   
<script>"text/javascript">   
dojo.require("dojo.widget.Tree");   
dojo.require("dojo.widget.TreeNode");   
dojo.require("dojo.widget.TreeSelector");   
dojo.require("dojo.widget.TreeRPCController");   
dojo.require("dojo.widget.TreeLoadingController");   
dojo.require("dojo.widget.TreeContextMenu");   
</script>   
2、在body中放置TreeWidget,TreeLoadingController中的RPCUrl="treeServlet"为从后台获取数据的servlet名称,TreeNode中的expandLevel表示树初始张开级别
<div dojoType="TreeLoadingController" RPCUrl="treeServlet" widgetId="treeController" DNDController="create"><!--</span-->div>   
<div dojoType="TreeSelector" widgetId="treeSelector"><!--</span-->div>   
<div dojoType="Tree" DNDMode="between" selector="treeSelector" widgetId="bandTree" controller="treeController">   
<div dojoType="TreeNode" title="root" widgetId="root" objectId="root" isFolder="true" childIconSrc="images/comm.gif" expandLevel="1"/>   
3、建立TreeSelector事件处理函数
function treeSelectFired() {   
    // get a reference to the treeSelector and get the selected node    
    var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');   
    var treeNode = treeSelector.selectedNode;   
    // get a reference to the songDisplay div   
    var hostDiv = document.getElementById("songDisplay");   
    var isFolder = treeNode['isFolder'];   
    //alert(isFolder);   
    if ( !isFolder) {   
       var song = treeNode['title'];   
       var url = treeNode['url'];   
       link(url);   
    } else {    
    }   
}   
4、将select事件处理函数关联到treeSelector
function init() {    
    //get a reference to the treeSelector   
    var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');   
    //connect the select event to the function treeSelectFired()   
    dojo.event.connect(treeSelector,'select','treeSelectFired');    
}   
dojo.addOnLoad(init);   
二、主要java代码及数据结构
1、Gnmk.java中tree的属性
 private String id;     
 private String gnmkdm;  //功能模块代码   
private String gnmksm;  //功能模块说明   
private String gnmktb;  //功能模块图标   
 private String gnmklj;  //功能模块路径   
 private String gnmkmc;  //功能模块名称   
private String gnmksj;  //功能模块上级代码   
private String gnmkbz;  //功能模块标志(‘N'为叶节点)   
2、HSQLDB内存数据库加载SQL(db.sql)
CREATE TABLE GNMK (ID VARCHAR, GNMKDM VARCHAR, GNMKMC VARCHAR, GNMKLJ VARCHAR, GNMKTB VARCHAR, GNMKBZ VARCHAR, GNMKSJ VARCHAR);     
INSERT INTO GNMK VALUES ('d098a59f0b765c30010b765d6b780001', '01', '一级目录1', null, 'system.gif', 'Y', '');     
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830001', '0101', '二级目录1', 'cxtjAction.do', 'system.gif', 'N', '01');     
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830001', '0102', '二级目录2', 'cxtjAction.do', 'system.gif', 'N', '01');     
INSERT INTO GNMK VALUES ('d098a59f0b765c30010b765d6b780002', '02', '一级目录2', null, 'system.gif', 'Y', '');     
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '0201', '二级目录1', 'cxtjAction.do', 'system.gif', 'N', '02');     
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '0202', '二级目录2', 'cxtjAction.do', 'system.gif', 'Y', '02');     
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '020201', '三级目录1', 'cxtjAction.do', 'system.gif', 'N', '0202');     
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '020202', '三级目录2', 'cxtjAction.do', 'system.gif', 'N', '0202');    
3、TreeServlet .java主要代码,在getGnmkByParent(String gnmksj)方法中可以实现自己的业务,DEMO中使用GnmkDAO
public class TreeServlet extends HttpServlet {   
    private static final long serialVersionUID = 1L;   
    protected void doGet(HttpServletRequest request,   
            HttpServletResponse response) throws ServletException, IOException {   
        String action = request.getParameter("action");   
        System.out.println("action b=>" + action);   
        System.out.println("action b=>" + action);   
        String data = request.getParameter("data");   
        if (action.equalsIgnoreCase("getChildren")) {   
            JSONTokener jsonTokener = new JSONTokener(data);   
            JSONObject jsonObject = (JSONObject) jsonTokener.nextValue();   
            JSONObject parentNodeObject = (JSONObject) jsonObject.get("node");   
            response.setContentType("text/json; charset=gb2312");   
            PrintWriter out = response.getWriter();   
            out.write(getChildren(parentNodeObject));   
        } else {   
        }   
    }   
    private String getChildren(JSONObject parentNodeObject) {   
        JSONArray result = new JSONArray();   
        String parentObjectId = parentNodeObject.getString("objectId");// id 唯一   
        // String parentWidgetId = parentNodeObject.getString("widgetId");// dm   
        parentObjectId = parentObjectId.equalsIgnoreCase("root") ? ""   
                : parentObjectId;   
        System.out.println("parentObjectId=>" + parentObjectId);   
        // 获取子功能模块   
        List listGnmk = this.getGnmkByParent(parentObjectId);   
        System.out.println("listGnmk=>" + listGnmk.size());   
        if (listGnmk != null) {   
            Iterator itGnmk = listGnmk.iterator();   
            while (itGnmk.hasNext()) {   
                Gnmk qxgnmk = (Gnmk) itGnmk.next();   
                try {   
                    JSONObject jsonGnmkObject = new JSONObject();   
                    String gnmkbz = qxgnmk.getGnmkbz();   
                    boolean isFolder = gnmkbz.equalsIgnoreCase("Y") ? true   
                            : false;   
                    jsonGnmkObject.put("title", qxgnmk.getGnmkmc());   
                    jsonGnmkObject.put("isFolder", isFolder);   
                    jsonGnmkObject.put("widgetId", qxgnmk.getGnmkdm());   
                    jsonGnmkObject.put("objectId", qxgnmk.getGnmkdm());   
                    jsonGnmkObject.put("childIconSrc", "images/"   
                            + qxgnmk.getGnmktb());   
                    jsonGnmkObject.put("url", qxgnmk.getGnmklj());   
                    result.put(jsonGnmkObject);   
                } catch (JSONException e) {   
                    e.printStackTrace();   
                }   
            }   
        }   
        return result.toString();   
    }   
    private List getGnmkByParent(String gnmksj) {   
        GnmkDAO gnmkDao = new GnmkDAO();   
        return gnmkDao.getGnmkByParent(gnmksj);   
    }   
}   
三、关于DEMO的其它配置说明
1、实现javax.servlet.ServletContextListener接口的contextInitialized方法来加载HSQLDB及其数据,ContextListener.java主要代码 
public void contextInitialized(ServletContextEvent event) {   
    try {   
        // load the driver   
        Class.forName("org.hsqldb.jdbcDriver");   
        // create the table and add sample data   
        InputStreamReader in = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("db.sql"));   
        BufferedReader reader = new BufferedReader(in);   
        DBUtils.setupDatabase(reader);   
    } catch (ClassNotFoundException e) {   
        e.printStackTrace();   
    }   
}   
2、web.xml相关配置
<listener>   
    <listener-class>   
       dojo.sample.ContextListener   
    <!--<span class="tag"--><!--</span-->listener-class>   
<!--</span-->>  
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树 
下载

Javascript 相关文章推荐
js cookies 常见网页木马挂马代码 24小时只加载一次
Apr 13 Javascript
开发插件的两个方法jquery.fn.extend与jquery.extend
Nov 21 Javascript
AngularJS中取消对HTML片段转义的方法例子
Jan 04 Javascript
javascript实现动态导入js与css等静态资源文件的方法
Jul 25 Javascript
js addDqmForPP给标签内属性值加上双引号的函数
Dec 24 Javascript
利用JavaScript实现栈的数据结构示例代码
Aug 02 Javascript
vue侧边栏动态生成下级菜单的方法
Sep 07 Javascript
微信小程序实现左右列表联动
May 19 Javascript
仿ElementUI实现一个Form表单的实现代码
Apr 23 Javascript
关于Vue中$refs的探索浅析
Nov 05 Javascript
vue下拉刷新组件的开发及slot的使用详解
Dec 23 Vue.js
three.js 实现露珠滴落动画效果的示例代码
Mar 01 Javascript
tbody元素支持嵌套的注意方法
Mar 24 #Javascript
xml 与javascript结合的问题解决方法
Mar 24 #Javascript
用prototype实现的简单小巧的多级联动菜单
Mar 24 #Javascript
this[] 指的是什么内容 讨论
Mar 24 #Javascript
javascript对象的property和prototype是这样一种关系
Mar 24 #Javascript
Ajax一统天下之Dojo整合篇
Mar 24 #Javascript
dojo 之基础篇(三)之向服务器发送数据
Mar 24 #Javascript
You might like
php is_writable判断文件是否可写实例代码
2016/10/13 PHP
PHP设计模式之适配器模式定义与用法详解
2018/04/03 PHP
jquery中常用的SET和GET
2009/01/13 Javascript
javascript 面向对象思想 附源码
2009/07/07 Javascript
jQuery模拟超链接点击效果代码
2013/04/21 Javascript
jquery选择符快速提取web表单数据示例
2014/03/27 Javascript
Javascript 拖拽的一些高级的应用(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
JavaScript中创建字典对象(dictionary)实例
2015/03/31 Javascript
被遗忘的javascript的slice() 方法
2015/04/20 Javascript
JS实现文字掉落效果的方法
2015/05/06 Javascript
JS实现带提示的星级评分效果完整实例
2015/10/30 Javascript
检查表单元素的值是否为空的实例代码
2016/06/16 Javascript
JS插件plupload.js实现多图上传并显示进度条
2016/11/29 Javascript
vue之数据交互实例代码
2017/06/20 Javascript
微信小程序页面缩放式侧滑效果的实现代码
2018/11/15 Javascript
js实现无缝轮播图
2020/03/09 Javascript
python中利用xml.dom模块解析xml的方法教程
2017/05/24 Python
OpenCV模板匹配matchTemplate的实现
2019/10/18 Python
Tensorflow不支持AVX2指令集的解决方法
2020/02/03 Python
python pip如何手动安装二进制包
2020/09/30 Python
H5 canvas实现贪吃蛇小游戏
2017/07/28 HTML / CSS
HTML5响应式(自适应)网页设计的实现
2017/11/17 HTML / CSS
阿迪达斯印度官方商城:adidas India
2017/03/26 全球购物
全球领先美式家具品牌:Ashley爱室丽家居
2017/08/07 全球购物
北美女性服装零售连锁店:maurices
2019/06/12 全球购物
德国在线购买葡萄酒网站:Geile Weine
2019/09/24 全球购物
会计助理的岗位职责
2013/11/29 职场文书
会计专业职业规划:规划自我赢取未来
2014/02/12 职场文书
安全责任书模板
2014/07/22 职场文书
公司股东出资证明书
2014/11/01 职场文书
个人专业技术总结
2015/03/05 职场文书
中学生打架检讨书之500字
2019/08/06 职场文书
解决redis sentinel 频繁主备切换的问题
2021/04/12 Redis
利用Python多线程实现图片下载器
2022/03/25 Python
《遗弃》开发商删推文要跑路?官方回应:还在开发
2022/04/03 其他游戏
浅谈为什么我的 z-index 又不生效了
2022/07/15 HTML / CSS