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

 看了“使用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-->>  
 
下载

时间: 2024-10-26 15:59:20

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

ajax 动态加载数据提示没有更多内容加载了

问题描述 ajax 动态加载数据提示没有更多内容加载了 怎么判断所有的数据已经加载完毕,提示没有更多内容加载了? if(data=='') 这个判断有误,求高人指点 解决方案 如果是分页你自己服务器端计算好总页数赋值给js变量,然后js设置一个当前页变量,每次加载后和总量对比就好了,干么多请求一次服务器由服务器返回空内容来控制是否加载完呢.. 解决方案二: 不知道你想问什么,data是什么?你的返回值怎么判断没有内容了.你的判断有误怎么得出的结论?有误的时候data什么值 解决方案三: data

在jsp上添加treeview,用ajax动态加载节点

问题描述 在jsp上添加treeview,用ajax动态加载节点,哪位高手帮一下,急用? 解决方案 解决方案二:树的JSP<HTML><HEAD><TITLE>主菜单</TITLE><linkrel="stylesheet"type="text/css"href="../../css/style.css"/><METAhttp-equiv=Content-Typecontent=&

jquery ajax()动态加载脚本文件的例子

上次说的jquery动态加载脚本,使用的是getScript(您可以点击相关文章查看),缺点和优点都说了.封装的函数是不自带缓存功能的,默认每次加载都刷新本地脚本.这样的一个特点对于网速不是很快的网站来说,那就是一个漫长的等待,虽然页面已经加载完毕了,但脚本还在路上,访客会以为脚本加载失败,就会反复的刷新页面,结果每次加载脚本都是重新获取的,造成资源的中断和大量的服务器请求.为了解决这个问题,我自己写了个方法,哈哈,当然是根据getScript把ajax方法打包到一个函数里便于多次复用. <!D

用ajax动态加载需要的js文件_AJAX相关

习惯了用java,在java中,需要某个类直接import就可以了,所以做javascript的时候也想实现这个效果. 前段时间,用了下dojo,里面的dojo.require的功能很不错,一看代码,晕了,一大堆东西,唉-还是自己写个简单点的,dojo.require可以引入包,我就只做一个导入js文件的. 开始用的document.write,执行顺序不对了,这是在后面进行导入,而我们总是在前面执行中就需要导入的js,这样,执行中就会报"某某未定义",就是顺序问题了. 接着,我就想用

求高手指教,关于ajax动态加载下拉框的

问题描述 最近在弄毕业设计,是使用SSH框架开发的web项目.有一张课题表project,有一个projectlevel字段,字段为1,2,3,4时分别对应项目,课题,子课题,专题.并且通过fatherid字段相互关联.现在我要使用ajax实现一个这样的功能:有一个选择层级下拉框:里面有4个option:项目,课题,子课题,专题.当选择项目后,便出现一个下拉框:所属项目,并将projectlevel为1的projectname全部加载到所属项目下拉框中.当选择课题后,便出现2个下拉框,分别是所属

ajax实现加载数据功能

加载数据的具体代码,供大家参考,具体内容如下 1.xssj.php <script src="jquery-3.2.0.min.js"></script> <title>无标题文档</title> </head> <body> <h1>显示数据</h1> <select id="sel"> </select> <input type=&quo

用ajax动态加载需要的js文件

习惯了用java,在java中,需要某个类直接import就可以了,所以做javascript的时候也想实现这个效果. 前段时间,用了下dojo,里面的dojo.require的功能很不错,一看代码,晕了,一大堆东西,唉-还是自己写个简单点的,dojo.require可以引入包,我就只做一个导入js文件的. 开始用的document.write,执行顺序不对了,这是在后面进行导入,而我们总是在前面执行中就需要导入的js,这样,执行中就会报"某某未定义",就是顺序问题了. 接着,我就想用

Ajax动态加载数据库示例_AJAX相关

复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title

Ajax动态加载数据库示例

复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title