论坛首页 Web前端技术论坛

EXT2的动态BorderLayout组件

浏览 5240 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-08-01   最后修改:2009-08-01
因为问答频道询问这个问题,自己也遇到过,以前是用动态改变south大小来实现的,尝试直接实现一个动态的BorderLayout,发现很简单,下面代码改写自BorderLayout的代码,实现BorderLayout区域的动态增减:
布局控制器的代码:
Ext.layout.DynamicBorderLayout = Ext.extend(Ext.layout.BorderLayout, {
	onLayout : function(ct, target) {
		var collapsed = [];
		target.position();
		if (!this.rendered) {
			target.addClass('x-border-layout-ct');
			this.rendered = true;
		}
                //这部分代码直接从上面this.rendered的条件移出来,增加typeof this[pos] == "undefined"的判断
		var items = ct.items.items;
		for (var i = 0, len = items.length; i < len; i++) {
			var c = items[i];
			var pos = c.region;
			if (typeof this[pos] == "undefined")
			{
				if (c.collapsed) {
					collapsed.push(c);
				}
				c.collapsed = false;
				if (!c.rendered) {
					c.cls = c.cls ? c.cls + ' x-border-panel' : 'x-border-panel';
					c.render(target, i);
				}
				this[pos] = pos != 'center' && c.split ?
							new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
							new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
				this[pos].render(target, c);
			}
		}
                //删除掉不需要的区域属性 
		this.removeNotExistsRegion(ct.items);
		var size = target.getViewSize();
		if (size.width < 20 || size.height < 20) { // display none?
			if (collapsed) {
				this.restoreCollapsed = collapsed;
			}
			return;
		} else if (this.restoreCollapsed) {
			collapsed = this.restoreCollapsed;
			delete this.restoreCollapsed;
		}

		var w = size.width, h = size.height;
		var centerW = w, centerH = h, centerY = 0, centerX = 0;

		var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
		if (!c) {
			throw 'No center region defined in BorderLayout ' + ct.id;
		}

		if (n && n.isVisible()) {
			var b = n.getSize();
			var m = n.getMargins();
			b.width = w - (m.left + m.right);
			b.x = m.left;
			b.y = m.top;
			centerY = b.height + b.y + m.bottom;
			centerH -= centerY;
			n.applyLayout(b);
		}
		if (s && s.isVisible()) {
			var b = s.getSize();
			var m = s.getMargins();
			b.width = w - (m.left + m.right);
			b.x = m.left;
			var totalHeight = (b.height + m.top + m.bottom);
			b.y = h - totalHeight + m.top;
			centerH -= totalHeight;
			s.applyLayout(b);
		}
		if (west && west.isVisible()) {
			var b = west.getSize();
			var m = west.getMargins();
			b.height = centerH - (m.top + m.bottom);
			b.x = m.left;
			b.y = centerY + m.top;
			var totalWidth = (b.width + m.left + m.right);
			centerX += totalWidth;
			centerW -= totalWidth;
			west.applyLayout(b);
		}
		if (e && e.isVisible()) {
			var b = e.getSize();
			var m = e.getMargins();
			b.height = centerH - (m.top + m.bottom);
			var totalWidth = (b.width + m.left + m.right);
			b.x = w - totalWidth + m.left;
			b.y = centerY + m.top;
			centerW -= totalWidth;
			e.applyLayout(b);
		}

		var m = c.getMargins();
		var centerBox = {
			x: centerX + m.left,
			y: centerY + m.top,
			width: centerW - (m.left + m.right),
			height: centerH - (m.top + m.bottom)
		};
		c.applyLayout(centerBox);

		if (collapsed) {
			for (var i = 0, len = collapsed.length; i < len; i++) {
				collapsed[i].collapse(false);
			}
		}

		if (Ext.isIE && Ext.isStrict) { // workaround IE strict repainting issue
			target.repaint();
		}
	},
	removeNotExistsRegion:function(items) {
		var regions = ["north","south","west"];
		for (var i = 0; i < regions.length; i++)
		{
			if (this[regions[i]] && !items.find(function(item) {
				return item.region == regions[i]
			}))
			{
				this[regions[i]] = undefined;
			}
		}
	}
})
Ext.Container.LAYOUTS['dynamicborder'] = Ext.layout.DynamicBorderLayout;


可运行的例子:
Ext.onReady(function() {
	var view = new Ext.Viewport({
		layout:"fit",
		items:{
			layout:"dynamicborder",
			items:[{
				title: 'Main Content',
				region:'center',
				margins: '5 5 0 0',
				tbar:[{
					text:"增加南",
					handler:function() {
						var container = view.items.items[0];
						var region = container.find("region", "south")[0];
						if (region)
						{
							return;
						}
						container.add({
							title: 'South Panel',
							region: 'south',
							height: 100,
							minSize: 75,
							maxSize: 250,
							margins: '0 5 5 5'
						});
						container.doLayout();
					}
				},{
					text:"去除南",
					handler:function() {
						var container = view.items.items[0];
						var region = container.find("region", "south")[0];
						container.remove(region);
						container.doLayout();
					}
				},{
					text:"增加西",
					handler:function() {
						var container = view.items.items[0];
						var region = container.find("region", "west")[0];
						if (region)
						{
							return;
						}
						container.add({
							title: 'West Panel',
							region:'west',
							margins: '5 0 0 5',
							cmargins: '5 5 0 5',
							width: 200,
							minSize: 100,
							maxSize: 300
						});
						container.doLayout();
					}
				},{
					text:"去除西",
					handler:function() {
						var container = view.items.items[0];
						var region = container.find("region", "west")[0];
						container.remove(region);
						container.doLayout();
					}
				}]

			}]
		}
	})
})
   发表时间:2008-08-03  
非常感谢你的文章..........

不过 我在你有次的回复关于EXTJS 释放内存的方式

可以稍微指点下吗?

你说的去掉MODAL 还有SHADOW

主要是去掉哪些关键代码?

很容易都去掉出错了。。。。

MODAL:..

SHADOW:..

只去掉这样的吗?

打扰之处见谅......

愿你工作顺利
0 请登录后投票
   发表时间:2008-08-04  
嗯,关于内存释放的问题,确认了问题的原因,怎样解决不清楚。modal:false,shadow:false可以,但是相应的特性就没有了
0 请登录后投票
   发表时间:2008-08-09  
当动态添加、删除splitregion时, splitBar删不掉, 需要手工删除。
0 请登录后投票
   发表时间:2008-08-09  
上面的问题,现在这样解决:
if (region) {
	var splitBar = Ext.DomQuery.selectNode("div[@class*='x-layout-split x-layout-split-west']");
	if(splitBar) {
		//alert(splitBar.id);
		Ext.get(splitBar.id).remove();
	}
	container.remove(region);
	container.doLayout();
}
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics