日期:2014-05-16  浏览次数:20461 次

ExtJS实现异步Tree的节点搜索

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


效果图:

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

???????? 一、 先展开树的所有节点,然后再在树中搜索

?

Ext.onReady(function() {
            Ext.QuickTips.init();
            Ext.BLANK_IMAGE_URL = "../../resources/images/default/s.gif";
            var mytree = new Ext.tree.TreePanel({
		region: 'center',
		title : "简单Extjs动态树",
                //el : "container",
                animate : true, //展开,收缩动画,false时,则没有动画效果    
                collapsible : true,
                enableDD : true,//不仅可以拖动,还可以通过Drag改变节点的层次结构(drap和drop)
                enableDrag : true,//仅仅drop 
                rootVisible : true,//false不显示根节点,默认为true 
                autoScroll : true,
                autoHeight : true,
                width : 150,
				//tbar:new Ext.Toolbar(),
				tbar:[' ',
					new Ext.form.TextField({
						width:150,
						emptyText:'快速检索',
						enableKeyEvents: true,
						listeners:{
							keyup:function(node, event) {
								findByKeyWordFiler(node, event);
							},
							scope: this
						}
					})
				],
				root:new Ext.tree.AsyncTreeNode({
					id:"root",  
                    text:"树的根",  
                    leaf:false, 
					//expanded:true,
					children: [{
						id: 'level',
						text: '用户类型',
						children: [{
							id: 'allLevel',
							text: '全部',
							leaf: true
						}, {
							id: 'noSupport',
							text: '无支持',
							leaf: true
						}, {
							id: 'month',
							text: '包月',
							leaf: true
						}, {
							id: 'year',
							text: '包年',
							leaf: true
						}, {
							id: 'always',
							text: '终身',
							leaf: true
						}]
					}, {
						id: 'outOfDate',
						text: '是否过期',
						children: [{
							id: 'allOutOfDate',
							text: '全部',
							leaf: true
						}, {
							id: 'notOutOfDate',
							text: '未过期',
							leaf: true
						}, {
							id: 'alreadyOutOfDate',
							text: '已过期',
							leaf: true
						}]
					}, {
						id: 'report',
						text: '统计图表',
						children: [{
							id: 'levelReport',
							text: '按用户类型',
							leaf: true
						}, {
							id: 'outOfDateReport',
							text: '按是否过期',
							leaf: true
						}]
					}]
            }),
                lines : true//节点间的虚线条
            });
			//mytree.expandAll();
            
            //mytree.render();
			/*
			var filterTreeFiled = new Ext.form.TextField({
				width:150,
				emptyText:'快速检索',
				enableKeyEvents: true
			});
			
			var tbar = mytree.getTopToolbar();
			tbar.add(filterTreeFiled);
			tbar.doLayout();*/

			var timeOutId = null;

			var treeFilter = new Ext.tree.TreeFilter(mytree, {
				clearBlank : true,
				autoClear : true
			});

			// 保存上次隐藏的空节点
			var hiddenPkgs = [];
			var findByKeyWordFiler = function(node, event) {
				clearTimeout(timeOutId);// 清除timeOutId
				mytree.expandAll();// 展开树节点
				// 为了避免重复的访问后台,给服务器造成的压力,采用timeOutId进行控制,如果采用treeFilter也可以造成重复的keyup
				timeOutId = setTimeout(function() {
					// 获取输入框的值
					var text = node.getValue();
					// 根据输入制作一个正则表达式,'i'代表不区分大小写
					var re = new