利用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 相关文章推荐
jquery 经典动画菜单效果代码
Jan 26 Javascript
jQuery 自动增长的文本输入框实现代码
Apr 02 Javascript
如何判断元素是否为HTMLElement元素
Dec 06 Javascript
js获取url中&quot;?&quot;后面的字串方法
May 15 Javascript
谷歌浏览器不支持showModalDialog模态对话框的解决方法
Sep 22 Javascript
javascript的函数作用域
Nov 12 Javascript
jquery手风琴特效插件
Feb 04 Javascript
JavaScript实现简单的双色球(实例讲解)
Jul 31 Javascript
Vue2.0设置全局样式(less/sass和css)
Nov 18 Javascript
通过 JS 判断页面是否有滚动条的实现方法
Apr 05 Javascript
js实现图片3D轮播效果
Sep 21 Javascript
vue 在methods中调用mounted的实现操作
Aug 07 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部分常见问题总结
2006/10/09 PHP
PHP函数extension_loaded()用法实例
2015/01/19 PHP
IOS 开发之NSDictionary转换成JSON字符串
2017/08/14 PHP
PHPExcel 修改已存在Excel的方法
2018/05/03 PHP
thinkPHP+LayUI 流加载实现功能
2019/09/27 PHP
实现局部遮罩与关闭原理及代码
2013/02/04 Javascript
JQuery的$命名冲突详细解析
2013/12/28 Javascript
jQuery实现数秒后自动提交form的方法
2015/03/05 Javascript
jQuery设置和移除文本框默认值的方法
2015/03/09 Javascript
wangEditor编辑器失去焦点后仍然可以在原位置插入图片分析
2015/05/06 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
一个简单不报错的summernote 图片上传案例
2016/07/11 Javascript
js无法获取到html标签的属性的解决方法
2016/07/26 Javascript
微信小程序 wxapp内容组件 icon详细介绍
2016/10/31 Javascript
vue.js国际化 vue-i18n插件的使用详解
2017/07/07 Javascript
原生JS实现简单的倒计时功能示例
2018/08/30 Javascript
Vue监听数据渲染DOM完以后执行某个函数详解
2018/09/11 Javascript
Vue刷新修改页面中数据的方法
2018/09/16 Javascript
详解React 服务端渲染方案完美的解决方案
2018/12/14 Javascript
使用vuepress搭建静态博客的示例代码
2019/02/14 Javascript
vue + typescript + 极验登录验证的实现方法
2019/06/27 Javascript
[34:44]Liquid vs TNC Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
使用Py2Exe for Python3创建自己的exe程序示例
2018/10/31 Python
python实现微信小程序用户登录、模板推送
2019/08/28 Python
将python安装信息加入注册表的示例
2019/11/20 Python
python代码实现将列表中重复元素之间的内容全部滤除
2020/05/22 Python
深入理解Python 多线程
2020/06/16 Python
python中的垃圾回收(GC)机制
2020/09/21 Python
解决python3中os.popen()出错的问题
2020/11/19 Python
浅析HTML5 Landmark
2020/09/11 HTML / CSS
德国EGOIST网店:销售畅销的设计师品牌
2017/04/18 全球购物
初中化学教学反思
2014/01/23 职场文书
乌鸦喝水教学反思
2014/02/07 职场文书
网吧最新创业计划书范文
2014/03/27 职场文书
应届生求职自荐信
2014/07/04 职场文书
爱的奉献演讲稿
2014/09/10 职场文书