`
WaterSugar
  • 浏览: 93706 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

Ext中TreePanel控件和TabPanel控件搭配测试

    博客分类:
  • Ajax
阅读更多

 

  在实际的项目中,左边树形菜单,提供各种功能点击,右边一个面板,随着左边节点的选择表现不同的功能内容,这是一个相当经典的布局,在Ext框架中,有两个控件TreePanel和TabPanel刚好完成这些功能,本文就这两个控件的搭配使用和点击左边树节点引起右边内容变化的方法作一个简单的介绍。首先看下面的具体的代码。

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>TabPanel和Tree控件搭配测试</title>
<link rel="stylesheet" type="text/css" media="all" href="../ext/resources/css/ext-all.css" />
<script type="text/javascript" src="../ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../ext/ext-all.js"></script>
<script type="text/javascript" src="../ext/build/locale/ext-lang-zh_CN.js"></script>
<script type="text/javascript">Ext.BLANK_IMAGE_URL = '../ext/resources/images/default/s.gif';</script>
<script type="text/javascript">
//左边功能树
var menuTree = new Ext.tree.TreePanel({
	region:'west',
	title:'功能菜单',
	width:180,
	minSize:150,
	maxSize:200,
	split:true,
	autoScroll:true,
	autoHeight:false,
	collapsible:true,
	rootVisable:false, //不显示根节点
	root:new Ext.tree.TreeNode({
		id:'root',
		text:'功能菜单',
		draggable:false,
		expanded:true
	})
});

//添加第一个节点(html)
menuTree.root.appendChild(new Ext.tree.TreeNode({
	id:'htmlPanel',
	text:'通过html打开',
	listeners:{
		'click':function(node, event) {
			event.stopEvent();
			var n = contentPanel.getComponent(node.id);
			if (!n) { //判断是否已经打开该面板
				n = contentPanel.add({
					'id':node.id,
					'title':node.text,
					closable:true,  //通过html载入目标页
					html:'<iframe scrolling="auto" frameborder="0" width="100%" height="100%" src="iframe.html"></iframe>'
				});
			}
			contentPanel.setActiveTab(n);
		}
	}
}));

//添加第二个节点(autoLoad)
menuTree.root.appendChild(new Ext.tree.TreeNode({
	id:'autoLoadPanel',
	text:'通过autoLoad打开',
	listeners:{
		'click':function(node, event) {
			event.stopEvent();
			var n = contentPanel.getComponent(node.id);
			if (!n) { ////判断是否已经打开该面板
				n = contentPanel.add({
					'id':node.id,
					'title':node.text,
					closable:true,
					autoLoad:{url:'auto.php', scripts:true} //通过autoLoad属性载入目标页,如果要用到脚本,必须加上scripts属性
				});
			}
			contentPanel.setActiveTab(n);
		}
	}
}));

//添加第三个节点(function)
menuTree.root.appendChild(new Ext.tree.TreeNode({
	id:'functionPanel',
	text:'通过函数打开',
	listeners:{
		'click':function(node, event) {
			event.stopEvent();
			var n = contentPanel.getComponent(node.id);
			if (!n) {
				var p = new fnPanel();
				p.id = node.id;
				p.title = node.text;
				n = contentPanel.add(p);
			}
			contentPanel.setActiveTab(n);
		}
	}
}));

//通过扩展来构建要创建的面板
fnPanel = Ext.extend(Ext.Panel, {
	closable:true,
	autoScroll:true,
	layout:'fit', //如果用函数来创建该面板的话,布局必须设置为fit,否则不会显示该面板中的内容

	//创建面板内容
	createFormPanel:function() {
		return new Ext.form.FormPanel({
			buttonAlign:'center',
			labelAlign:'right',
			frame:false,
			bodyBorder:false,
			bodyStyle:'padding:25px',
			items:[{
				xtype:'textfield',
				fieldLabel:'用户名',
				width:350,
				name:'username'
			},{
				xtype:'textfield',
				fieldLabel:'密 码',
				width:350,
				name:'password'
			}],
			buttons:[{text:'登陆'}, {text:'取消'}]
		});
	},

	//重装控件初始化函数,在该函数中完成面板中内容的初始化
	initComponent:function() {
		fnPanel.superclass.initComponent.call(this);
		this.fp = this.createFormPanel();
		this.add(this.fp);
	}
});

//右边具体功能面板区
var contentPanel = new Ext.TabPanel({
	region:'center',
	enableTabScroll:true,
	activeTab:0,
	items:[{
		id:'homePage',
		title:'首页',
		autoScroll:true,
		html:'<div style="position:absolute;color:#ff0000;top:40%;left:40%;">Tree控件和TabPanel控件结合功能演示</div>'
	}]
});

Ext.onReady(function(){
	new Ext.Viewport({
		layout:'border', //使用border布局
		defaults:{activeItem:0},
		items:[menuTree, contentPanel]
	});
});
</script>
</head>
<body>
</body>
</html>

 

  上面代码中,构建了两个控件menuTree和contentPanel,menuTree用来显示具体功能菜单,contentPanel用来展示具体功能内容,menutTree中的节点是通过appendChild()方法手动加上去的,而且为了介绍方便,每个节点都添加了一个处理点击事件的函数,在具体应用中,还可以使用AsyncTreeNode()和TreeLoader()动态载入节点,下面着重介绍点击树节点引起功能区变化的方法,上面代码中用到了三种方法。

 

  (1)通过TabPanel控件的html属性配合<iframe>实现。该方法是利用html属性中包含<iframe>的语法来调用另一个页面,具体见代码。该方法实现比较简单,只要重新编辑一个html文件即可以了,而且如果要在新生成的页面中再使用Ext的控件也比较简单,也比较好控制,只要像一个页面情况下使用就可以了,因为他本身就是一个完整的html文件。而该方法的缺点就是资源占用厉害,是三种方法中占有最厉害的,而且还有Ext的重复加载的问题(不知道Ext库中考虑这种情况了没有),另外就是新的页面载入速度也是最慢的。

 

  (2)通过TabPanel控件的autoLoad属性实现。该方法是利用autoLoad属性,它有很多参数,其中有两个比较重要,url表示要载入的文件,scripts表示载入的文件是否含有脚本,该属性相当重要,如果在新的页面中要创建Ext控件,必须指定该参数。该方法实现较前一个复杂,因为引入的文件不是一个完整的html文件,有可能只是内容的一部分,但是资源占用较少,而且载入速度较快(它有一个载入指示),但缺点就是如果是载入的是一个单纯html文件(*.html),在字符编码上处理很麻烦,经常出现乱码,我提供的源码中是一个PHP文件,用PHP文件也只是一个作用,改变输出的字符编码,用html能够实现同样的功能,但会是乱码,我不知道怎样解决这个问题。

 

  (3)通过自己构建新的面板来实现。该方法是通过继承Panel面板,然后在该面板中加入要显示的内容,再重载initComponet()方法,最后把该面板添加到TabPanel中,该方法中一个要注意的地方,新生成的页面布局一定要用fit,否则该面板中的内容不能显示出来。该方法是所有方法中最复杂的,而且由于采用了fit布局,新生成的页面中的元素不好控制,我例子中的表单就生成的比较乱。但载入速度是最快的,可能是少了载入指示吧,资源占用跟第二种方法差不多。

 

  上面三种方法中,我比较喜欢第二种实现方面,简单好控制,而且还有一个载入指示。不知道大家有没有其他的方法。一起讨论讨论。

分享到:
评论
21 楼 swap 2012-02-09  
我找了那么多资料,不如你的几行代码,忒精悍了。
20 楼 bevis.cn 2009-03-09  
我也是被这个TabPanel稿得不行了
19 楼 379548695 2008-09-10  
楼主看到加我qq379548695跟你讨论下!
18 楼 wangchunfei 2008-07-28  
我加载一个jsp文件,里面包含一些ExtJs,但是都加载不成功,不知道为什么?
17 楼 zhaosenrui 2008-07-27  
关于第二种方法,我把autoLoad的url换同目录下的test.html,为什么老是显示不出来?
16 楼 paradox 2008-06-20  
lims 写道
paradox 写道
有一个问题请教一下,是关于第二种方法的:
是不是多个tab页对应的页面里不能有相同的<div id='id'></div>
如:
autoLoad:{url:'auto.php', scripts:true}
autoLoad:{url:'auto1.php', scripts:true}
是不是auto.php和auto1.php里不能同时有<div id='divid'></div>

楼上说的是对的,不能有任何的相同的DIV,估计用种方法就要自己做一个ID控制的方法了

不能有任何的相同的DIV,这个限制太致命了,有没有什么解决方法?
15 楼 lims 2008-06-20  
paradox 写道
有一个问题请教一下,是关于第二种方法的:
是不是多个tab页对应的页面里不能有相同的<div id='id'></div>
如:
autoLoad:{url:'auto.php', scripts:true}
autoLoad:{url:'auto1.php', scripts:true}
是不是auto.php和auto1.php里不能同时有<div id='divid'></div>

楼上说的是对的,不能有任何的相同的DIV,估计用种方法就要自己做一个ID控制的方法了
14 楼 paradox 2008-06-20  
有一个问题请教一下,是关于第二种方法的:
是不是多个tab页对应的页面里不能有相同的<div id='id'></div>
如:
autoLoad:{url:'auto.php', scripts:true}
autoLoad:{url:'auto1.php', scripts:true}
是不是auto.php和auto1.php里不能同时有<div id='divid'></div>
13 楼 paradox 2008-06-20  
有一个问题请教一下,是关于第二种方法的:
是不是多个tab页对应的页面里不能有相同的<div id='id'></div>
如:
autoLoad:{url:'auto.php', scripts:true}
autoLoad:{url:'auto1.php', scripts:true}
是不是auto.php和auto1.php里不能同时有<div id='divid'></div>
12 楼 vicksong 2008-06-15  
好象第二种方法也不是可以随意载入文件的,有很多的情况下就报错......
11 楼 huangqiqun 2008-06-14  
我想显示一个gridPanel
10 楼 huangqiqun 2008-06-14  
我想显示一个gridPanel
9 楼 wabe033 2008-05-12  
// 生成标签页
var tab = new Ext.TabPanel({
region : 'center',
enableTabScroll : true,
activeTab : 0,
height : 300,
margins : '0 5 5 0',
items : [{
id : 'homePage',
title : '我的工作台',
autoScroll : true,
autoLoad : {
url : "portal.htm",
scripts : true
} // 首页默认的加载页面

}]
});

Ext.onReady(function() {
viewport = new Ext.Viewport({
layout : 'border',
items : [tab]
});
});

//为什么我总是显示 loading 呢?? 也不报错。。。新手求指教。
8 楼 WaterSugar 2008-04-06  
你可以在autoLoad载入的那个文件中加入一个<div id="r"></div>,然后在你的panel中renderTo:'r',可以看看我的这篇文章http://jfp.iteye.com/blog/178889,是上面这篇文章的一个补充,其中有这个问题的解决方法。
7 楼 chenxinliang 2008-04-06  
请教个问题,我用autoLoad属性实现,属性里面设置的一个页面是用ext实现的一个面板,里面有borderlayout实现,包括一个panel和一个tab。为什么我设置了scripts属性这个页面显示不出来那
6 楼 WaterSugar 2008-04-02  
非常感谢你的建议。

我说的是如果返回HTML文件,因为在Apache服务器中设置的默认编码为GB2312,而我的HTML文件是UTF-8编码的,而且最后在客户端中显示的也是UTF-8编码,所以有一个UTF-8-->GB2312-->UTF-8的转换过程,而直接是HTML文件的话好像不会这样转换,所以我用了一个PHP文件,明确声明为UTF-8,也即header('Content-Type:text/html;charset=utf-8');

你说的在第三种方法中用doLayout()的方法,我试试看,看能不能实现。

再次感谢。
5 楼 gdipkf1986 2008-04-02  
php乱码是编码所至,所有服务器返回的数据必须是utf-8格式,所以你的php返回脚本应该是这样

return iconv("utf-8","gb2312",youJsonData);

//php中是不是iconv这个函数记不大清楚,但确实有一个转换编码的过程.

你的第三种方法我没有细看.但应该没有只能使用fit布局的限制.内容不能显示出来,可能tab面板需要重新布局,执行doLayout方法.

tabpanel.add(yourPanel).show().doLayout()

4 楼 WaterSugar 2008-03-31  
谢谢,我希望的是大家多提提其他想法。而且就上面提到的三种方法,我还在进一步研究,又有一些新的发现。
3 楼 supersi 2008-03-31  
做的不错,讲解也很细致,。雪中送炭。
。。。。。顶。。。
2 楼 nickevin 2008-03-31  
非常感谢  感激中 ...

相关推荐

Global site tag (gtag.js) - Google Analytics