摘要:在任何一个Tree树中,提供查找功能无疑会大大方便用户。不用睁大眼睛一级一级去展开,只要输入关键字,回车就能自动定位到节点,岂不快哉?然后再次回车查找下一个。这样的用户体验是相当完美的 ( 见《用户体验这点事儿》)。但在动态异步加载的Tree树中,客户端实现这样的功能就有点困难,因为节点是异步动态加载的。默认是没有全部从服务器端取回的,通常的做法是默认加载第一级,其他级的节点都是惰性按需加载的,用户点了才会展开。而对于这个没有完全加载的树,用户希望搜索节点,怎么实现?笨办法是先展开树的所有节点,然后再在树中搜索。这样的话在服务器数据量大的情况下会非常慢。这里的实现方法是在服务器端的WebService查找,通过AJAX返回第一个匹配节点的路径Path,然后展开这个路径,选中这个搜索到节点。查找下一个(FindNext)的实现方法是…
在任何一个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代码略…
服务器端代码略…
- ExtJS+ASP.NET实现真实的进度条显示服务器端长时间操作的进度
- ExtJS+ASP.NET实现异步Tree的节点搜索和查找下一个(FindNext)
- ExtJS+ASP.NET实现Tree节点的拖动(DragDrop)
- ExtJS+ASP.NET实现Grid到Tree的拖动(DragDrop)
- ExtJS+ASP.NET实现单文件上传(FileUpload)
- ExtJS之ASP.NET服务器端实现ashx和asmx处理客户端请求
- 使用YUI Compressor和DOS批处理脚本压缩JavaScript和CSS
- 优化JavaScript
- 区分JavaScript中的underfined,null和NaN