ExtJS+ASP.NET实现异步Tree的节点搜索和查找下一个(FindNext)

摘要:在任何一个Tree树中,提供查找功能无疑会大大方便用户。不用睁大眼睛一级一级去展开,只要输入关键字,回车就能自动定位到节点,岂不快哉?然后再次回车查找下一个。这样的用户体验是相当完美的 ( 见用户体验这点事儿)。但在动态异步加载的Tree树中,客户端实现这样的功能就有点困难,因为节点是异步动态加载的。默认是没有全部从服务器端取回的,通常的做法是默认加载第一级,其他级的节点都是惰性按需加载的,用户点了才会展开。而对于这个没有完全加载的树,用户希望搜索节点,怎么实现?笨办法是先展开树的所有节点,然后再在树中搜索。这样的话在服务器数据量大的情况下会非常慢。这里的实现方法是在服务器端的WebService查找,通过AJAX返回第一个匹配节点的路径Path,然后展开这个路径,选中这个搜索到节点。查找下一个(FindNext)的实现方法是…

sfr (提供查找功能的树Tree无疑会大大方便用户)

在任何一个Tree树中,提供查找功能无疑会大大方便用户。不用睁大眼睛一级一级去展开,只要输入关键字,回车就能自动定位到节点,岂不快哉?然后再次回车查找下一个。这样的用户体验是相当完美的。

但在动态异步加载的Tree树中,客户端实现这样的功能就有点困难,因为节点是异步动态加载的。默认是没有全部从服务器端取回的,通常的做法是默认加载第一级,其他级的节点都是惰性按需加载的,用户点了才会展开。而对于这个没有完全加载的树,用户希望搜索节点,怎么实现?笨办法是先展开树的所有节点,然后再在树中搜索。这样的话在服务器数据量大的情况下会非常慢。

这里的实现方法是在服务器端的WebService查找,通过AJAX返回第一个匹配节点的路径Path,然后展开这个路径,选中这个搜索到节点。

在ExtJS中,AsyncTreeNode是异步节点,TreeLoader实现对树结点的异步加载,即使服务器取到大量的数据,也没有问题,异步加载能保证性能和节点的按需加载。服务端需要生成指定格式的Json字符串。

下面是显示树Tree并从服务端取到第一级节点的代码:

客户端JavaScript: 指定TreeLoader,加根节点,并默认展开第一级。

 1: var tree = new Ext.tree.TreePanel({
 2:  
 3:// 此处省略
 4:  
 5: loader:new Ext.tree.TreeLoader({
 6: dataUrl:"myTreeNodesJson.ashx", //服务器端WebService
 7: listeners:{
 8: "loadexception":function(loader,node,response){
 9: node.loaded = false;
 10: //node.reload.defer(10,node);//不停的加载,直到true
 11: }
 12: }
 13: }),
 14:  
 15:// 此处省略
 16:  
 17: })
 18:  
 19: //根节点
 20: var root=new Ext.tree.AsyncTreeNode({
 21: id:"root",
 22: text:"根节点",
 23:  
 24: qtip:'根节点提示',
 25:  
 26: draggable:false,
 27: expanded:true
 28: });
 29: tree.setRootNode(root);
 30: tree.render();
 31:  
 32: tree.root.expand(false, false); //默认展开第一级 
 33: //tree.on("click", treeClickHandler);

服务端myTreeNodesJson.ashx代码: 供TreeLoader使用,输出Json格式字符串的树节点。

 1: using System;
 2: using System.Web;
 3: using System.Collections.Generic;
 4: using System.Web.Script.Serialization;
 5:  
 6:  
 7:  
 8: //定义jsondata类,存放节点数据
 9:  
 10: public class jsondata 
 11: {
 12: public string id;
 13: public string text;
 14: public bool leaf;
 15: public List<jsondata> children=new List<jsondata>();//存放子节点
 16: }
 17:  
 18:  
 19: public class myTreeNodesJson: IHttpHandler {
 20: public List<jsondata> jsdata=new List<jsondata>();
 21: public void ProcessRequest (HttpContext context) {
 22: for (int i = 1; i < 5; i++)
 23: {
 24: jsondata jd = new jsondata();
 25: jd.id="num"+i;
 26: jd.text = "节点"+i;
 27: jd.leaf = false;
 28: for (int j = 1; j < 3; j++)
 29: {
 30: jsondata subjd = new jsondata();
 31: subjd.id = "sub" + j;
 32: subjd.text = "子节点" + j;
 33: subjd.leaf = true;
 34: jd.children.Add(subjd);
 35: } 
 36: jsdata.Add(jd);
 37: } 
 38: context.Response.Write(ToJson(jsdata.ToArray()));//ToArray()在IE里面好像缺了不行
 39: }
 40: public bool IsReusable {
 41: get {
 42: return false;
 43: }
 44: }
 45:  
 46:  
 47:  
 48: //序列化对象为json数据
 49:  
 50: public string ToJson(object o)
 51: {
 52: //序列化对象为json数据
 53: JavaScriptSerializer j = new JavaScriptSerializer();
 54: return j.Serialize(o);
 55: }
 56:  

查找节点的实现方法是调用服务器端的WebService查找,通过AJAX返回第一个匹配节点的路径Path,然后展开这个路径,选中这个搜索到节点。查找下一个(FindNext)的实现方法是,每一次客户端把上次已经匹配到底节点的id也作为参数传给服务端,服务端自动查找此节点下一个并返回。

客户端代码:

 1: var lastSearch;
 2:  
 3: function onNodeSearchClick(btn){
 4: var vlu = textBoxNodeSearch.getValue();
 5: if(vlu=='') return;
 6: var startNodeID = null; //New search 新的查找
 7: if(lastSearch != '' && lastSearch == vlu) // Find next 查找下一个
 8: {
 9: if(selectedNodeID && selectedNodeID != 'root')
 10: startNodeID = selectedNodeID ;
 11: }
 12: lastSearch = vlu;
 13:  
 14: //调用服务端Webservice查找
 15: MyServerWebService.SearchNode(vlu, startNodeID , onSearchSuccessCallback, onSearchFailCallback);
 16:  
 17: }
 18:  
 19: function onSearchSuccessCallback(result){
 20: if(result=='') 
 21: alert( "没有找到任何节点!");
 22: else
 23: {
 24:  
 25: //展开路径,注意Path是以节点id加上/来间隔的。
 26: tree.expandPath('tree/root/' + result, 'id', onExpandPathComplete);
 27: }
 28: }
 29:  
 30: function onExpandPathComplete(bSuccess, oLastNode) {
 31: if(!bSuccess) return;
 32: //focus 节点,并选中节点!
 33: selectNode(oLastNode);
 34: }
 35:  
 36:  
 37: function selectNode(node){
 38: if(node)
 39: {
 40:  
 41:     //focus 节点,并选中节点!以下3行代码缺一不可!!
 42: node.ensureVisible();
 43: node.select() ;
 44: node.fireEvent('click', node);
 45: }
 46: }
 47:  
 48:  
 49:  
 50: 服务端WebService代码略…

服务器端代码略…

posted on 2009-04-25 17:23  Mainz  阅读(5428)  评论(10编辑  收藏  举报

导航