`
8366
  • 浏览: 810407 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

ext 异步加载树完整版

    博客分类:
  • ext
阅读更多

 

 

       最近做一个项目,需要一个树形菜单,本来可以使用DTree实现,也比较简单,不过觉得最近EXT火的很,于是考虑使用EXt 的tree ,做一个异步刷新的树,也就是在点了父亲节点才会去异步夹杂孩子结点,先发个图晒晒!

 

 

 

   实现原理:树的每一个节点都有自己的ID,和它的父亲节点的ID,还有自己的文本内容,以及点击后在哪个frame中打开哪个连接,是否是叶子节点等内容,树的第一级节点的父亲节点的ID我们将它置为0,以后每次点解一个非叶子节点的时候,我们都去异步加载他的所有孩子结点,将信息组装成JSON字符串,返回给前台,前台的EXT Tree使用JSON数据构造树

 

主要步骤: 

 

第一步:构造 树的 表结构

 

CREATE TABLE `ump_functions` (           
                 `item_id` int(11) NOT NULL,            
                 `item_name` varchar(60) DEFAULT NULL,  
                 `parent_id` int(11) DEFAULT NULL,      
                 `isleaf` tinyint(1) DEFAULT NULL,      
                 `Item_url` varchar(60) DEFAULT NULL,   
                 `remark` varchar(120) DEFAULT NULL,    
                 PRIMARY KEY (`item_id`)                
               ) ENGINE=InnoDB DEFAULT CHARSET=gbk 

 

 

第二步 构造和表关联的 javaBean对象 FuctionTreeNode.java

 

 

package cn.com.xinli.tree.bean;
/**
 * 
 * @author huxl
 *
 * 代表系统左边的导航树的节点,根据节点的信息 异步动态加载 extTree
 * 根节点的 父节点的id是0
 */
public class FuctionTreeNode 
{

	/*树节点id*/
    private int id;
    /*树节点名称*/
    private String text;
    /*树节点url*/
    private String href;
    /*点击叶子在指定的 frame中刷新*/
    private String hrefTarget="_blank";
    /*是否是叶子节点 */
    private boolean leaf; 
    /*树节点的样式*/
    private String cls;
	public int getId()
	{
		return id;
	}
	public void setId(int id)
	{
		this.id = id;
	}
	public String getText()
	{
		return text;
	}
	public void setText(String text)
	{
		this.text = text;
	}
	public String getHref()
	{
		return href;
	}
	public void setHref(String href)
	{
		this.href = href;
	}
	public String getHrefTarget()
	{
		return hrefTarget;
	}
	public void setHrefTarget(String hrefTarget)
	{
		this.hrefTarget = hrefTarget;
	}
	
	
	
	public boolean isLeaf()
	{
		return leaf;
	}
	public void setLeaf(boolean leaf)
	{
		this.leaf = leaf;
	}
	public String getCls()
	{
		return cls;
	}
	public void setCls(String cls)
	{
		this.cls = cls;
	}
    
	
}

 

第三步 根据节点id去找节点的孩子结点  FuctionTreeDaoImpl.java

 

package cn.com.xinli.tree.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import cn.com.xinli.tree.dao.FuctionTreeDao;
import cn.com.xinli.tree.bean.FuctionTreeNode;
import cn.com.xinli.tree.util.DBUtil;


public class FuctionTreeDaoImpl implements FuctionTreeDao
{
	private Logger log=Logger.getLogger(FuctionTreeDaoImpl.class);
	public List<FuctionTreeNode>  queryNodeById(String nodeId) throws Exception
	{
		
		Connection conn=null;
		PreparedStatement pstmt;
		ResultSet rs;
		
		
		List<FuctionTreeNode> nodeList=new ArrayList<FuctionTreeNode>();
		try {
			conn=DBUtil.getConnection();
		//	String sql="select t.* from  ump_functions t ,ump_role_function s where t.item_id = s.item_id and t.parent_id="+nodeId+" and s.role_id="+roleId ;
			String sql="select t.* from  ump_functions t where t.parent_id="+nodeId;
			
			
			log.info("sql:"+sql);
			pstmt=conn.prepareStatement(sql);
			//pstmt.setInt(1, nodeId);
			rs=pstmt.executeQuery();
	
			while(rs.next())
			{
				FuctionTreeNode node=new FuctionTreeNode();
				
			    node.setId(rs.getInt("item_id"));
			    node.setText(rs.getString("item_name"));
			    node.setLeaf(rs.getBoolean("isleaf"));
			    node.setHref(rs.getString("item_url"));
				nodeList.add(node);
			}
			return nodeList;
		} 
		catch (Exception e) 
		{
			log.info("查询节点出错:", e);
			throw new Exception("查询节点出错");
		} 
		finally
		{
			if(conn!=null)
			{
				try
				{
					conn.close();
				}
				catch (SQLException e)
				{
					log.info("数据库连接出错:", e);
					throw new Exception("数据库连接出错");
				}
			}
		}
	}
	

}

  

第4步: 写ext 的 tree 的js

 

 

 

/*
 * Ext JS Library 2.0.1
 * Copyright(c) 2006-2008, Ext JS, LLC.
 * licensing@extjs.com
 *
 * http://extjs.com/license
 */
Ext.onReady(function(){
    
    //从本地加载树的图片
    Ext.BLANK_IMAGE_URL = 'extjs/resources/images/vista/s.gif'; 
    var Tree = Ext.tree;
    var tree = new Tree.TreePanel({
        el:'tree-div',
         rootVisible:true,     //隐藏根节点 
                border:true,          //边框 
                animate:true,         //动画效果 
                autoScroll:true,      //自动滚动 
                enableDD:false,       //拖拽节点              
                containerScroll:true,          
        loader: new Tree.TreeLoader({
       // dataUrl:'http://localhost:9090/struts2/menus.action'
        })
    });

    // set the root node
    var root = new Tree.AsyncTreeNode({
        text: '统一监控平台',
        draggable:false,
        //树的根节点的ID设置成0有个好处就是初始化树的时候默认先加载父亲节点为0的孩子结点
        id:'0'
    });
    	tree.setRootNode(root);
	  	tree.on('beforeload', 
        function(node)
        { 
 			tree.loader.dataUrl='http://localhost:9090/struts2/menus!loadTree.action?pid='+node.id
	 		//tree.loader.dataUrl='treedata2.txt'
        }); 
    	// render the tree
    	tree.render();
    	root.expand(); 
     	//展开树的所有节点,有一些特殊需求会要求我们一次展开所有的节点,传true
    	//root.expand(true);
    	//只展开根节点
    	root.expand(); 
	});

 

还有一个Ext 发送Ajax 请求的一个小例子 主要是使用到了  Ext.Ajax.request 

 

 

 

附件中 是 整个项目 ,下载即可使用

1.需要建立数据库和表结构 sql 和数据脚本 见上面

2.讲项目放在TOMCat 可以直接运行

 

 

对于前台接收json字符串 的一个思考(2010.05.23):

 

 

对于上面的例子,我们是使用 menu.jsp 来接收后台的返回的json字符串

menu.jsp  的内容很简单 2行

 

<%@ taglib prefix="s" uri="/struts-tags" %>
<s:property value="menuString" escape="false"/>

 

其中:

 

<s:property>标签的escape属性默认值为true,即不解析html代码,直接将其输出。
如:novel.NTitle的值为

<font color=red>邪门</font>

则<s:property value="#novel.NTitle">就直接输出原值。若想让标签解析html标签输出:

邪门

则将escape设为false

<s:property value="#novel.NTitle" escape="false"/>

 

 

这个例子中我们希望 输出解析后的值,不想看到html标签

 

 <action name="menus" class="cn.com.xinli.tree.action.QueryNodeAction">
            <result name="success">/menu.jsp</result>
  </action>

 

并且使用的是 <package name="struts2" extends="struts-default">

 

 

我们把 后台的json字符串放在了 menuString 字符串中,

 

 

而extends="struts-default" 下面的action 都是页面跳转的意思

<result name="success">/menu.jsp</result>
的意思就是 action执行后 跳转到 menu.jsp

 

tree.loader.dataUrl='http://localhost:9090/struts2/menus!loadTree.action?pid='+node.id

是ext 中的方法 他是用来接受json字符串的 ,首先看看 tree.loader.dataUrl 的源码,可见

tree.loader.dataUrl 是一个ajax请求 接受返回结果,而loadTree.action 返回一个json字符串,刚好绑定在

 

menu.jsp 中,因此 tree.loader.dataUrl  得到了json字符串,由于是ajax请求,也不会引起页面跳转

 

 

  requestData : function(node, callback){
        if(this.fireEvent("beforeload", this, node, callback) !== false){
            this.transId = Ext.Ajax.request({
                method:this.requestMethod,
                url: this.dataUrl||this.url,
                success: this.handleResponse,
                failure: this.handleFailure,
                scope: this,
                argument: {callback: callback, node: node},
                params: this.getParams(node)
            });
        }else{
            // if the load is cancelled, make sure we notify
            // the node that we are done
            if(typeof callback == "function"){
                callback();
            }

 

 

 

这种从后台得到 json 字符串,传递到前台一个Jsp页面的做法有点 臃肿,比如我们还需要在 action中 使用json.jar

 

使用下面的方法 将一个对象转化为 json 字符串

 

 JSONArray jsonObject = JSONArray.fromObject(menus);
  menuString = jsonObject.toString();

 

其实 strtus2已经为我们提供了action 返回 json字符串的支持,下面我们改造 以前手工得到json字符,用一个Jsp页面来接受的例子,换成 使用strtus2 json 插件支持

 

步骤:

 

1.首先在以前的项目中加入

 

    jsonplugin-0.32.jar

 

2. 修改 后台构造Json串的方法

 

 

package cn.com.xinli.tree.action;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import cn.com.xinli.tree.bean.FuctionTreeNode;
import cn.com.xinli.tree.dao.FuctionTreeDao;
import cn.com.xinli.tree.dao.impl.FuctionTreeDaoImpl;
public class QueryNodeAction extends BaseAction
{
	private Logger log=Logger.getLogger(QueryNodeAction.class);
    private String menuString;
    /*返回给前台树的Json 对象,使用struts2 json插件可以直接将这个对象转换为
     * json字符串
     * 需要在struts.xml中进行配置
     * 
     * */
    private List<FuctionTreeNode> menusList;
    
    public List<FuctionTreeNode> getMenusList() {
		return menusList;
	}

	public void setMenusList(List<FuctionTreeNode> menusList) {
		this.menusList = menusList;
	}

	public String getMenuString() {
        return menuString;
    }

    public void setMenuString(String menuString) {
        this.menuString = menuString;
    }

  
    /*异步加载树*/
    public String loadTree()
    {	 
    	  log.info("开始根据父亲节点查找孩子节点");
	      HttpServletRequest request=getRequest();
	      String nodeId=request.getParameter("pid");
	      log.info("父亲节点的ID是:"+nodeId);
	      FuctionTreeDao treeDao=new  FuctionTreeDaoImpl();
      try 
      {
      	menusList=treeDao.queryNodeById(nodeId);
    	 log.info("孩子结点的数目是:"+menusList.size());
   	  	//以下三行代码可以让返回的JSON数据不包含需要过滤的字段
    	 /*
    	JsonConfig config = new JsonConfig();
    	//过滤cls属性
   	  	config.setExcludes( new String[]{"cls"});
   	  	JSONArray jsonObject2 = JSONArray.fromObject(menus,config);
   	  	*/
   	  	//JSONArray jsonObject = JSONArray.fromObject(menus);
   	  //	menuString = jsonObject.toString();
  
       }
       catch (Exception e) 
       {
       		e.printStackTrace();
          
       }
       
  
       return "success";
    }
    /*ajax 调用,返回json 字符串*/
    public String ajax()
    {
    	//HttpServletResponse resp= getResponse(); 
    	//resp.setContentType("application/json;charset=UTF-8");
    	HttpServletRequest req= getRequest(); 
    	try
    	{
    		System.out.println("从前台Ajax请求参数是:"+req.getParameter("foo"));
    		menuString="[{success:true,msg:'修改权限成功'}]";
			//resp.getWriter().write("{success:true,msg:'修改权限成功'}");
		} 
    	catch (Exception e)
    	{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
    	return "aa";
    }
  
	
	
}

 

3 .修改 struts.xml 关键是 修改 packega 的 extends="json-default"

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
	<package name="struts2" extends="json-default">
		<action name="login" class="cn.com.xinli.tree.action.LoginAction">
			<result name="success">/result.jsp</result>
			<result name="input">/login2.jsp</result>
			<result name="error">/login2.jsp</result>
		</action>                              
		 <action name="menus" class="cn.com.xinli.tree.action.QueryNodeAction">
            <result name="success" type="json">
            	<param name="root">menusList</param>
            </result>
            
            <result name="aa" type="json">
            	<param name="root">menuString</param>
            </result>
        </action>
        
      
	</package>
    
</struts>

 

 

 其中

 

<result name="success" type="json">
             <param name="root">menusList</param>
            </result>

 

代表 这个action的返回结果是 json字符串, 其中json串的 root节点 为 menusList

 

如果你返回的对象 不需要那个属性 可以这么写,则格式化  page 对象为json字符串的时候

 

conditions,limit,start,success,objCondition 几个属性将被忽略

 

<param name="root">page</param>
    <param name="excludeProperties">
     conditions,limit,start,success,objCondition
    </param>

 

 相反的 如果只需要对象的 某个属性转化为Json串 可以这么写

<result type="json">
    <param name="includeProperties">
     success,msg
    </param>
   </result>

 

 

 

附件中 extTreeJSON.rar 为修改以后例子 ,其中 依赖的Lib 可以下载 以前的lib

 

 

 

  • data.rar (652 Bytes)
  • 下载次数: 321
分享到:
评论
5 楼 wlz728 2013-01-30  
我的树点下级时不重新加载,是哪的问题呢,下边这段js是在什么地方用到了呢?不知道放在什么位置
requestData : function(node, callback){
4 楼 wmaaaa08 2012-07-02  
楼主 求指点
3 楼 allstar2012 2012-05-21  
能说下ext解析tree的原理思路是什么样子的?
2 楼 8366 2010-08-14  
poincare 写道
能请教一下用 dtree怎么实现Ajax加载吗?


当然可以了,这个是我们公司的一个大牛改造的Dtree 异步树

http://programmerdigest.cn/2009/12/607.html
你可以参考下!!
1 楼 poincare 2010-08-11  
能请教一下用 dtree怎么实现Ajax加载吗?

相关推荐

    ext中文帮助文档最终版

    10. **国际化支持**:"ext中文帮助文档最终版"意味着EXT库有中文文档,对于中文开发者来说,更容易理解和学习EXT的API和使用方法。 EXT 2.0.2作为EXT 2.0的一个补丁版本,很可能包含了对一些已知问题的修复和性能...

    ext 3.3 中文 chm

    此外,EXT 3.3 还支持Ajax交互,能够轻松实现异步数据加载,提升用户体验。 在EXT 3.3 中,布局管理器(Layout Manager)是一个重要的特性,它负责管理组件的大小和位置,确保它们在页面上正确地排列和适应不同屏幕...

    ext 2.2中文版

    "ext 2.2中文版"是ExtJS的2.2版本的中文文档,对于中国开发者来说,这是一个极其宝贵的资源,因为它消除了语言障碍,使得学习和使用ExtJS变得更加方便。 在"Ext 2.2中文版"中,你可以找到以下主要知识点: 1. **...

    ext.net 开发版

    8. **开发工具**:EXT.NET提供了一套完整的开发工具,包括Visual Studio插件、设计器、调试器等,便于开发者快速构建和调试EXT.NET应用。 9. **社区支持**:EXT.NET社区版1.3还包括了社区的支持和资源,开发者可以...

    ext2.0正式版本

    EXT库基于AJAX技术,它允许开发者通过异步方式与服务器进行数据交互,提高用户体验,使页面无需刷新就能加载新数据。EXT提供了多种AJAX组件,如Grid Panel、Form Panels等,这些组件不仅具备完整的功能,还支持各种...

    ext—core3.0

    需要注意的是,虽然EXT Core 3.0 是EXT框架的基础版本,它可能不包含EXT完整版的所有特性。如果需要更多高级功能,如图表、图表组件、拖放支持等,你可能需要考虑使用EXT JS的完整版本。 总的来说,EXT Core 3.0 是...

    ext1.1 api(chm_en)

    开发者可以使用EXT的AJAX API进行数据的异步加载和更新,实现动态和实时的Web应用。 最后,EXT1.1 API文档还覆盖了数据存储(Data Store)和数据模型(Data Model)的概念,这对于处理和展示大量数据至关重要。数据...

    Ext22中文API(完整版)

    Ext2.2中文API(完整版)是一款专为开发者设计的文档资料,它详细介绍了ExtJS 2.2版本的JavaScript库,这是一个广泛用于构建富客户端Web应用的框架。此API文档提供了完整的中文翻译,方便中国开发者理解和使用ExtJS...

    EXT2_combobox_form.rar_combobox ext_ext

    1. 动态加载:可以配置为从服务器异步加载数据,只在需要时请求更多数据,提高性能。 2. 自动完成:当用户输入字符时,可以自动匹配列表中的项,提供用户友好的体验。 3. 多选:通过配置,combobox可以支持多选模式...

    ext后台经典实例

    1. **Ajax通信**:EXT使用Ext.Ajax类进行异步通信,与后台服务器交换数据。例如,当用户执行增删改查操作时,EXT会发送Ajax请求到指定的服务器端接口,然后接收并处理返回的数据。 2. **数据模型(Model)**:EXT中...

    Ext.NET官方案例

    在"Ext.NET.WebForms.Pro.2.2.0.Examples.Explorer"这个压缩包中,你将发现一个完整的例子浏览器,它按类别组织了所有官方示例,便于你逐个学习和参考。通过探索这些实例,你可以深入理解每个控件的工作原理,并将...

    《深入浅出Ext JS(第2版)》(清晰版)

    《深入浅出Ext JS(第2版)》是一本针对Web开发者的专业书籍,专注于讲解Ext JS这个强大的JavaScript框架。Ext JS是一个用于构建富互联网应用(RIA)的前端框架,它提供了一整套组件和工具,使开发者可以快速创建...

    ext-3.2.0 下载

    4. **远程数据交互**:EXT JS支持AJAX和JSONP技术,方便与服务器进行异步通信,实现数据的动态加载和提交。EXT 3.2.0可能进一步优化了这些功能,提高了数据处理效率。 5. **表单组件**:EXT JS提供了强大的表单处理...

    《深入浅出Ext JS(第2版)》书本代码

    《深入浅出Ext JS(第2版)》是一本专门探讨Ext JS这一JavaScript框架的权威书籍,其配套代码库包含了作者为了阐述各种概念和技术而编写的示例代码。Ext JS是一个用于构建富客户端Web应用程序的JavaScript库,尤其...

    EXT ,EXT.chm,ext中文

    6. **AJAX通信**:EXT内置了AJAX功能,方便与服务器进行异步通信,实现数据的动态加载和更新。 7. **强大的事件系统**:EXT的事件模型允许组件之间进行通信和交互,提高了代码的可复用性和模块化。 8. **可扩展性*...

    深入浅出EXT JS 第二版

    Ext JS提供了一套完整的数据管理方案,包括本地存储、远程数据加载、数据校验等,使开发人员能够高效地管理数据和处理数据交互。同时,Ext JS还拥有出色的动画效果库,能够实现丰富的视觉交互效果,增强用户体验。在...

    Ext3.0 api帮助文档

    Ext3.0 API是Ext JS库的一个重要版本,它提供了丰富...以上只是Ext3.0 API的一部分关键特性,完整的帮助文档会更深入地介绍每个类和方法,包括参数、返回值、示例代码等,帮助开发者实现高效且功能丰富的Web应用程序。

Global site tag (gtag.js) - Google Analytics