在ExtJS自己的TreeLoader中,当要实现从远程服务器端异步加载树节点信息的时候,都是通过请求服务器上的某一个URL来进行的,这个URL返回下面的信息:

[
{

id: 1,

text: 'A leaf Node',

leaf: true


},
{

id: 2,

text: 'A folder Node',


children: [
{

id: 3,

text: 'A child Node',

leaf: true

}]

}]


假如我们是直接通过类似DWR或EasyJWeb的远程脚本引擎在客户端直接调用服务器的业务方法,直接跳过了WEB(不需要Struts、JSP或其它Web层的代码)这一层,这时我们没有URL,这时该怎么办呢?这就需要使用到自定义的TreeLoader,下面我们通过一个实例来做简单的讲解。
看服务器端的ITopicCategoryService

publicinterface ITopicCategoryService
{

List<Node> loadCategory(Long id);

}

loadCategory方法返回一个类型为Node的列表,也就是返回指定id的下级分类信节点信息,Node对应树节点的信息,代码如下:

public class Node
{

private TopicCategory category;


Node(TopicCategory category)
{

this.category = category;

}


public String getId()
{

returncategory.getId().toString();

}


publicboolean getLeaf()
{

returncategory.getChildren().size() < 1;

}


public String getText()
{

returncategory.getName();

}


public String getQtip()
{

returncategory.getName();

}

}


Node在这里相当于一个简单适配器,其实就是把数据库中的日志分类实体适配成包树节点对象。
把ITopicCategoryService发布成可供客户端远程调用,使用EasyJWeb的话引如下面三个js:
<script type="text/javascript" src="/ejf/easyajax/prototype.js"></script>

<script type="text/javascript" src="/ejf/easyajax/engine.js"></script>

<script type="text/javascript" src="/ejf/easyajax/topicCategoryService.js"></script>


使用DWR的话引入下面的两个js:
<script type="text/javascript" src="/dwr/dwr/engine.js "></script>

<script type="text/javascript" src="/dwr/dwr/util.js "></script>

<script type="text/javascript" src="/dwr/dwr/interface/ topicCategoryService.js "></script>

这样我们可以在页使用下面的javascrpt来从服务器端获得某一个节点的子节点信息,代码如下:
function test()



{

topicCategoryService.loadCategory(1,function(ret)



{

alert("一共有"+ret.length+"个子节点");

}

}


如何让ExtJS的树面板能通过这个远程web脚本方法topicCategoryService.loadCategory来加载异步加载树节点信息呢?其实很简单,跟一般的使用没什么两样,树面板TreePanel的代码如下:

var tree = new Ext.tree.TreePanel(
{

autoScroll:true,

animate:true,

width:'100px',

height:'300px',

enableDD:true,

containerScroll: true,

loader: loader


root: new Ext.tree.AsyncTreeNode(
{

text: '日志分类',

id:'root'

});

});


然后区别是在loader部分,使用远程Web调用来加载树节点的loader,代码如下:

var loader=new WebInvokeTreeLoader(
{

fn:topicCategoryService.loadCategory

});


loader.on("beforeload",function(l,node)
{

l.args[0]=(node.id!='root'?node.id:"-1");

});


再回顾一下传统的直接通过url加载树节点的TreeLoader代码,如下所示:

var loader=new Ext.tree.TreeLoader(
{

url:'/topicCategory.ejf?cmd=getCategory&pageSize=-1&treeData=true'

});


loader.on("beforeloader",function(loader,node)
{

loader.baseParams.id=(node.id!='root'?node.id:"");

});

区别在于,远程脚本调用方式加载树节点信息使用的是WebInvokeTreeLoader,需要通过fn属性来指定用于加载数据的远程方法,并在beforeload事件处理器设置参数远程方法调用的参数值。而传统的树节点加载器是Ext.tree.TreeLoader,需要指定一个url来获得json数据。
WebInvokeTreeLoader是自定义的树加载器,代码其实比较简单,你可以自己写一个。本方案仅供参考,关于WebInvokeTreeLoader的源代码我已经传到了我用ExtJS开发的Blog示例网站wlr.easyjf.com上了,仅供VIP会员浏览,有兴趣的朋友可跟我联系。