预览:
![](http://clip2net.com/clip/m4134/1211963475-01-15kb.jpg)
demo.html:
<script type="text/javascript" src="js/Ext.ux.MyTreeLoader/MyTreeLoader.js"></script>
<script type="text/javascript" src="treeloader.js"></script>
<div id="tree-ct"></div>treeloader.js:
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//**
* @include "js/Ext.ux.MyTreeLoader/ColumnNodeUI.js"
* @include "js/Ext.ux.MyTreeLoader/MyTreeLoader.js"
* @include "js/Ext.ux.MyTreeLoader/TreeNodeProvider.js"
*/
Ext.BLANK_IMAGE_URL = 'js/ext-2.0/resources/images/default/s.gif';
var flag = true;// To toggle the refresh
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
Ext.onReady(function()
{
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var treeNodeProvider =
{
data : [],// Property in which are set the data to elaborate
dataUrl : 'addressBook.do?dispatch=queryAddressBook',
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
getNodes : function()
{ // Here you process your data
return Ext.decode(this.data);
},
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
setData : function(data)
{// Called internally by
// Ext.tree.MyTreeLoader by the method
// updateTreeNodeProvider
this.data = data;
},
scope : this
// Could be useful to use when you elaborates data to switch the
// context
not used in this example and it's not required
};
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var treeNodeProvider2 =
{
data : [],// Property in which are set the data to elaborate
dataUrl : 'companyGroup.do?dispatch=queryGroup',
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
getNodes : function()
{ // Here you process your data
return Ext.decode(this.data);
},
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
setData : function(data)
{// Called internally by
// Ext.tree.MyTreeLoader by the method
// updateTreeNodeProvider
this.data = data;
},
scope : this
// Could be useful to use when you elaborates data to switch the
// context
not used in this example and it's not required
};
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var myTreeLoader = new Ext.tree.MyTreeLoader(
{
treeNodeProvider : treeNodeProvider
});
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var myTreeLoader2 = new Ext.tree.MyTreeLoader(
{
treeNodeProvider : treeNodeProvider2
});
![](/Images/OutliningIndicators/InBlock.gif)
myTreeLoader.updateTreeNodeProvider(myTreeLoader);// if you want to
// "preload"
// the TreePanel with this
// data
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var ajaxCallGetDataForTree = function(inputParameters)
{
treePanel.body.mask("Loading data
");
setTimeout(ajaxCallbackGetDataForTree, 1000);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var ajaxCallbackGetDataForTree = function()
{
![](/Images/OutliningIndicators/InBlock.gif)
treePanel.body.unmask();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
treePanel.body.highlight('#c3daf9',
{
block : true
});
// Simulating that I have received the response that is treeData2 from
// the callback of the ajaxCall
var rootNode = treePanel.getRootNode();// get the rootnode
var loader = treePanel.getLoader();// Get the loader, note that is of
// type MyTreeLoader
loader.updateTreeNodeProvider(myTreeLoader);
loader.load(rootNode);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var ajaxCallGetDataForTree2 = function(inputParameters)
{
treePanel.body.mask("Loading data
");
setTimeout(ajaxCallbackGetDataForTree2, 1000);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var ajaxCallbackGetDataForTree2 = function()
{
![](/Images/OutliningIndicators/InBlock.gif)
treePanel.body.unmask();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
treePanel.body.highlight('#c3daf9',
{
block : true
});
// Simulating that I have received the response that is treeData2 from
// the callback of the ajaxCall
var rootNode = treePanel.getRootNode();// get the rootnode
var loader = treePanel.getLoader();// Get the loader, note that is of
// type MyTreeLoader
loader.updateTreeNodeProvider(myTreeLoader2);
loader.load(rootNode);
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
var flag = true;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var basePanelCfg =
{
title : "AJAX式多数据源及节点异步加载",
preloadChildren : true,
lines : false,
clearOnLoad : true,
rootVisible : false,
containerScroll : true,
frame : false,
collapsible : false,
animate : true,
loader : myTreeLoader,
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
tbar : [
{
text : "加载通讯录",
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
handler : function()
{
// Simulating change the treeNodeProvider of the loader
var rootNode = treePanel.getRootNode();// get the rootnode
var loader = treePanel.getLoader();// Get the loader, note that
// is of type MyTreeLoader
loader.setTreeNodeProvider(treeNodeProvider);
// Simulating an ajax call
ajaxCallGetDataForTree();
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
},
{
text : "加载组织",
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
handler : function()
{
// Simulating change the treeNodeProvider2 of the loader
var rootNode = treePanel.getRootNode();// get the rootnode
var loader = treePanel.getLoader();// Get the loader, note that
// is of type MyTreeLoader
loader.setTreeNodeProvider(treeNodeProvider2);
// Simulating a different ajax call
ajaxCallGetDataForTree2();
}
}]
};
![](/Images/OutliningIndicators/InBlock.gif)
var treePanel = new Ext.tree.TreePanel(basePanelCfg);
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var root = new Ext.tree.AsyncTreeNode(
{
text : 'Root',
draggable : false,
id : '1'
});
![](/Images/OutliningIndicators/InBlock.gif)
treePanel.setRootNode(root);
treePanel.render('tree-ct');
});
![](/Images/OutliningIndicators/None.gif)
js/Ext.ux.MyTreeLoader/MyTreeLoader.js:
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//*
* Version 0.2.3
*
* Ext.tree.MyTreeLoader
*
* @author Dott. Ing. Marco Bellocchi @date 24. April 2008 @license
* Ext.tree.MyTreeLoader.js is licensed under the terms of the Open Source LGPL
* 3.0 license.
*
* @include "js/Ext.ux.MyTreeLoader/ColumnNodeUI.js" @include
* "js/Ext.ux.MyTreeLoader/MyTreeLoader.js" @include
* "js/Ext.ux.MyTreeLoader/TreeNodeProvider.js"
*
* License details: http://www.gnu.org/licenses/lgpl.html
*/
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
Ext.tree.MyTreeLoader = function(config)
{
// @private
var canFireLoadEvent = true;// private
// @private
var treeNodeProvider = null;
// @private
var loading = false;
![](/Images/OutliningIndicators/InBlock.gif)
Ext.apply(this, config);
Ext.tree.MyTreeLoader.superclass.constructor.call(this, config);
// TO FIX I need to do that for retro compatibility, but you MUST use
// getTreeNodeProvider to have access to it!
treeNodeProvider = this.treeNodeProvider;
// dataUrl = this.dataUrl;
![](/Images/OutliningIndicators/InBlock.gif)
// @private
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var processResponse = function(o, node, callback)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
node.beginUpdate();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (var i = 0, len = o.length; i < len; i++)
{
var n = this.createNode(o[i]);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (n)
{
node.appendChild(n);
}
}
node.endUpdate();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (e)
{
canFireLoadEvent = false;
this.fireEvent("loadexception", this, node, treeNodeProvider.data);
}
// make sure we notify
// the node that we finished
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (typeof callback == "function")
{
callback();
}
if (canFireLoadEvent === true)
this.fireEvent("load", this, node, treeNodeProvider.data);// Passing
}.createDelegate(this);
![](/Images/OutliningIndicators/InBlock.gif)
// @private
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var requestData = function(node, callback)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (this.fireEvent("beforeload", this, node, callback) !== false)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
this.transId = Ext.Ajax.request(
{
method : this.requestMethod,
url : treeNodeProvider.dataUrl || treeNodeProvider.url,
// success: this.handleResponse,
success : handleResponse,
failure : this.fireEvent("loadexception", this, node,
treeNodeProvider.data),
scope : this,
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
argument :
{
callback : callback,
node : node
},
params : this.getParams(node)
});
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
canFireLoadEvent = false;
}
}.createDelegate(this);
![](/Images/OutliningIndicators/InBlock.gif)
// @private
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
var handleResponse = function(response)
{
var a = response.argument;
this.processResponse(response, a.node, a.callback);
this.fireEvent("load", this, a.node, response);
}.createDelegate(this);
![](/Images/OutliningIndicators/InBlock.gif)
// @public
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
this.load = function(node, callback)
{
canFireLoadEvent = true;// Reset the flag
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (this.clearOnLoad)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (node.firstChild)
{
var tmpNode = node.firstChild;
node.removeChild(tmpNode);
tmpNode.destroy();// Destroy actually cascades, see,
// http://extjs.com/forum/showthread.php?t=14993
}
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (this.doPreload(node))
{ // preloaded json children
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (typeof callback == "function")
{
callback();
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else if (treeNodeProvider)
{
requestData(node, callback);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
// @public
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
this.isLoading = function()
{
return loading;
}
![](/Images/OutliningIndicators/InBlock.gif)
// @public
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
this.updateTreeNodeProvider = function(obj)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (treeNodeProvider)
{
treeNodeProvider.setData(obj);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
// @public
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
this.getTreeNodeProvider = function()
{
return treeNodeProvider;
}
// Set a new treeNodeProvider
// @public
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
this.setTreeNodeProvider = function(newTreeNodeProvider)
{
if (newTreeNodeProvider == null
|| (typeof newTreeNodeProvider == 'undefined'))
throw 'setTreeNodeProvider, newTreeNodeProvider == null || (typeof newTreeNodeProvider == undefined)';
treeNodeProvider = newTreeNodeProvider;
}
![](/Images/OutliningIndicators/InBlock.gif)
};
Ext.tree.MyTreeLoader = Ext.extend(Ext.tree.MyTreeLoader, Ext.tree.TreeLoader);
![](/Images/OutliningIndicators/None.gif)