基于Ext异步加载tree的实例 - Seraph115 - JavaEye技术网站

来源:百度文库 编辑:神马文学网 时间:2024/07/03 08:22:10
2008-09-26
基于Ext异步加载tree的实例
使用JS生成树形结构的菜单是基于J2EE的B/S系统常用的UI方式。但长期以来的问题是同步(即一次加载整棵树)加载一棵完整的树给前台及后台同时带来压力,由于加载数据及渲染时间过长使用户体验度很低。Ajax的异步数据传输方式是解决此问题的较好方式,即每次只加载一层节点,当需要时才加载下级节点,这样页面无需一次加载解决了此问题。
Ext的TreePanel组件提供了此功能即异步树(asynchronism tree),使用其实现需以下两步:
后台数据加载的实现,并以JSON形式提供给前台。
前台Ext的Tree组件实现。
实现预览:

1. 首先是JavaBean的节点模型(Tree Node Model):
Java代码
/**
* Method: 异步加载树型结点

* Origin Time: 2008-8-15 下午03:56:28

*
* @author Seraph

* @email: seraph115@gmail.com

*/
public class AsyncTreeNode {
private String id;
private String text; // 结点显示名称
private boolean leaf; // 是否为叶子结点
private boolean disabled; // 是否可用
private String cls; // 显示的样式,file、folder
private String iconCls; // 结点图标样式
private String href; // 点击后时的链接
private String hrefTarget; // 在何frame中显示
private boolean draggable; // 是否可拖拽
// Omit the get and set method
... ...
}
/*** Method: 异步加载树型结点
* Origin Time: 2008-8-15 下午03:56:28
** @author Seraph
* @email: seraph115@gmail.com
*/public class AsyncTreeNode {private String id;private String text; // 结点显示名称private boolean leaf; // 是否为叶子结点private boolean disabled; // 是否可用private String cls; // 显示的样式,file、folderprivate String iconCls; // 结点图标样式private String href; // 点击后时的链接private String hrefTarget; // 在何frame中显示private boolean draggable; // 是否可拖拽// Omit the get and set method... ...}
数据库中的表结构:
COLUMN_NAME
DATA_TYPE
ID NUMBER
PARENT
NUMBER
TEXT VARCHAR2
LEAF VARCHAR2
DISABLED VARCHAR2
CLS
VARCHAR2
ICON_CLS
VARCHAR2
HREF
VARCHAR2
HREF_TARGET
VARCHAR2
取下级节点的接口定义:
Java代码
/**
* Method: 获取异步加载树型子结点

* Author: Seraph

* Origin Time: 2008-9-9 下午05:46:02

*
* @param menuId 当前结点的id
* @return 下级节点组成的List
*/
public List getLowerTreeNodes(String menuId);
/*** Method: 获取异步加载树型子结点
* Author: Seraph
* Origin Time: 2008-9-9 下午05:46:02
** @param menuId 当前结点的id* @return 下级节点组成的List*/public List getLowerTreeNodes(String menuId);
数据提供的Spring的Controller:
Java代码
/**
* Method:

* Origin Time: 2008-8-15 上午11:07:55

* @author Seraph

* @email: seraph115@gmail.com

*/
public class AsyncTreeProviderController extends JsonProviderController {
private TreeManager treeManager;
public void setTreeManager(TreeManager treeManager) {
this.treeManager = treeManager;
}
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String rootId = request.getParameter("id");
List list = treeManager.getLowerTreeNodes(rootId);
super.pushJsonResponse(response, list);
return null;
}
}
/*** Method:
* Origin Time: 2008-8-15 上午11:07:55
* @author Seraph
* @email: seraph115@gmail.com
*/public class AsyncTreeProviderController extends JsonProviderController {private TreeManager treeManager;public void setTreeManager(TreeManager treeManager) {this.treeManager = treeManager;}protected ModelAndView handleRequestInternal(HttpServletRequest request,HttpServletResponse response) throws Exception {String rootId = request.getParameter("id");List list = treeManager.getLowerTreeNodes(rootId);super.pushJsonResponse(response, list);return null;}}  此步将查询到的下级结点的List转换为JSON数据通过Ajax方式返回给Ext的TreePanel组件用以渲染下级结点。
PS: 推荐使用json-lib来转换javabean为json数据。下面是json-lib的maven的dependency。
Xml代码

net.sf.json-lib
json-lib
2.2.2

net.sf.json-libjson-lib2.2.2
2. JavaScript的Ext TreePanel组件实现:
Js代码
/**
* async-tree.js Power by YUI-EXT and JSON.
*
* @author Seraph
* @email seraph115@gmail.com
*/
var AsyncTree = {
author: "Seraph",
version: "0.1.0"
};
// -> Configuration of tree. e.g: CG[1]
var CG = {
1: "asyncTreeProvider.do",
2: "async"
};
// -> Root-node name in Chinese. e.g: CN[1]
var CN = {
1: "菜单",
2: "配置"
};
// -> Root-node ID of tree. e.g: ID[1]
var ID = {
1: "-1",
2: "-2"
};
Ext.onReady(function(){
var Tree = Ext.tree;
var myTreeLoader = new Ext.tree.TreeLoader({
url: CG[1]
});
myTreeLoader.on("beforeload", function(treeLoader, node) {
myTreeLoader.baseParams.id = node.attributes.id;
}, myTreeLoader);
var tree = new Tree.TreePanel({
el:'tree1',
autoScroll:true,
autoHeight: true,
border: false,
animate:true,
enableDD:true,
rootVisible:false,
containerScroll: true,
loader: myTreeLoader,
root: {
nodeType: CG[2],
text: CN[1],
id: ID[1]
}
});
tree.render();
tree.getRootNode().expand();
});
/*** async-tree.js Power by YUI-EXT and JSON.** @author Seraph* @email seraph115@gmail.com*/var AsyncTree = {author: "Seraph",version: "0.1.0"};// -> Configuration of tree. e.g: CG[1]var CG = {1: "asyncTreeProvider.do",2: "async"};// -> Root-node name in Chinese. e.g: CN[1]var CN = {1: "菜单",2: "配置"};// -> Root-node ID of tree. e.g: ID[1]var ID = {1: "-1",2: "-2"};Ext.onReady(function(){var Tree = Ext.tree;var myTreeLoader = new Ext.tree.TreeLoader({url: CG[1]});myTreeLoader.on("beforeload", function(treeLoader, node) {myTreeLoader.baseParams.id = node.attributes.id;}, myTreeLoader);var tree = new Tree.TreePanel({el:'tree1',autoScroll:true,autoHeight: true,border: false,animate:true,enableDD:true,rootVisible:false,containerScroll: true,loader: myTreeLoader,root: {nodeType: CG[2],text: CN[1],id: ID[1]}});tree.render();tree.getRootNode().expand();});