利用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 相关文章推荐
Javascript读取cookie函数代码
Oct 16 Javascript
JavaScript判断IE版本型号
Jul 27 Javascript
ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)
Sep 06 Javascript
jQuery实现磁力图片跟随效果完整示例
Sep 16 Javascript
jQuery常见的选择器及用法介绍
Dec 20 Javascript
jQuery实现简单的滑动导航代码(移动端)
May 22 jQuery
Vue全局分页组件的实现代码
Aug 10 Javascript
了解JavaScript中let语句
May 30 Javascript
js String.prototype.trim字符去前后空格的扩展
Aug 23 Javascript
解决Vue 给mapState中定义的属性赋值报错的问题
Jun 22 Javascript
JavaScript如何实现防止重复的网络请求的示例
Jan 28 Javascript
vue如何使用模拟的json数据查看效果
Mar 31 Vue.js
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分页类的代码
2011/05/18 PHP
解决cPanel无法安装php5.2.17
2014/06/22 PHP
JavaScript While 循环基础教程
2007/04/05 Javascript
jquery实现的带缩略图的焦点图片切换(自动播放/响应鼠标动作)
2013/01/23 Javascript
扩展js对象数组的OrderByAsc和OrderByDesc方法实现思路
2013/05/17 Javascript
c#+jquery实现获取radio和checkbox的值
2020/09/12 Javascript
html的DOM中document对象forms集合用法实例
2015/01/21 Javascript
jQuery与Ajax以及序列化
2016/02/01 Javascript
jQuery生成假加载动画效果
2016/12/01 Javascript
canvas绘制的直线动画
2017/01/23 Javascript
js正则表达式验证表单【完整版】
2017/03/06 Javascript
Vue组件中slot的用法
2018/01/30 Javascript
完美解决iview 的select下拉框选项错位的问题
2018/03/02 Javascript
Angular 5.x 学习笔记之Router(路由)应用
2018/04/08 Javascript
JS中判断某个字符串是否包含另一个字符串的五种方法
2018/05/03 Javascript
使用puppeteer爬取网站并抓出404无效链接
2018/12/20 Javascript
JavaScript变量作用域及内存问题实例分析
2019/06/10 Javascript
[01:08]DOTA2次级职业联赛 - Shield战队宣传片
2014/12/01 DOTA
[01:06:59]完美世界DOTA2联赛PWL S2 Magma vs FTD 第一场 11.29
2020/12/02 DOTA
python海龟绘图实例教程
2014/07/24 Python
python私有属性和方法实例分析
2015/01/15 Python
python生成IP段的方法
2015/07/07 Python
Python 可变类型和不可变类型及引用过程解析
2019/09/27 Python
Pyspark读取parquet数据过程解析
2020/03/27 Python
BCBG官网:BCBGMAXAZRIA
2017/12/29 全球购物
馥蕾诗美国官网:Fresh美国
2019/10/09 全球购物
C语言中一个结构不能包含指向自己的指针吗
2012/05/25 面试题
心理健康教育制度
2014/01/27 职场文书
求职信需要的五点内容
2014/02/01 职场文书
将相和教学反思
2014/02/04 职场文书
学校安全责任书
2014/04/14 职场文书
四风查摆剖析材料
2014/10/10 职场文书
2014年销售经理工作总结
2014/12/01 职场文书
五一劳动节活动总结
2015/02/09 职场文书
HTML+CSS+JS实现图片的瀑布流布局的示例代码
2021/04/22 HTML / CSS
Java 在线考试云平台的实现
2021/11/23 Java/Android