`
andy_ghg
  • 浏览: 290959 次
  • 性别: Icon_minigender_1
  • 来自: 扬州
社区版块
存档分类
最新评论

EXTJS组件化(四)---减少你的代码

阅读更多
代码量,BUG和维护成本是水涨船高的关系,这点应该不能被否认的,因此如何的减少代码的编写量成了很多人努力的一个方向.当然,这肯定不是为了偷懒

减少代码量的编写自然是对象的重复利用,以前所写的组件化,它确实是一个独立的对象,可以拿来重用,但是,写到最后会发现,这些组件往往只是使用了一次而已,而且根据需求的不同会发现这个组件根本就无法被重新使用了(定制性太强)

于是,我们就需要拆分这个组件,看看这些组件中都有哪些东西是经常被用到的.

比如导航栏,一排导航十多个按钮,他们都是按钮,但是他们的handler虽然都是切换显示页面,但是每个按钮所负责的页面却是不同的,曾经有人问过,我是不是要为每一个按钮都编写一个handler处理函数?

Ext.onReady(function(){
	var panel = new Ext.Panel({
		renderTo:Ext.getBody(),
		border:false,
		tbar: [{
		    xtype: 'buttongroup',
		    columns: 6,
		    title: '客户管理',
//		    defaults:{xtype:"xmenubutton"},
		    items: [{
		        text: '客户信息',
		        scale: 'large',
		        rowspan: 2, 
		        handler:function(){
		        	//TODO 处理
		        },
		        iconCls: 'menuDefault_32',
		        iconAlign: 'top'
		    },{
		        text: '新增客户',
		        scale: 'large',
		        rowspan: 2, 
		        handler:function(){
		        	//TODO 处理
		        },
		        iconCls: 'menuDefault_32',
		        iconAlign: 'top'
		    },{
		        text: '客户通讯录',
		        scale: 'large',
		        rowspan: 2, 
		        handler:function(){
		        	//TODO 处理
		        },
		        iconCls: 'menuDefault_32',
		        iconAlign: 'top'
		    }]
		}]
	});
});

这样写起来,一旦导航多了,就比较麻烦了,代码显得很乱,不好维护,怎么办?
也许有人会这么去写它:
Ext.onReady(function(){
	function onBtnClickHandler(btn){
		switch (btn.text){
			case "客户信息":
				//TODO
				alert("aaa");
				break;
			case "新增客户":
				//TODO
				break;
			case "客户通讯录":
				//TODO
				break;
		}
	}
	var panel = new Ext.Panel({
		renderTo:Ext.getBody(),
		border:false,
		tbar: [{
		    xtype: 'buttongroup',
		    columns: 6,
		    title: '客户管理',
		    items: [{
		        text: '客户信息',
		        scale: 'large',
		        rowspan: 2, 
		        handler:onBtnClickHandler,
		        iconCls: 'menuDefault_32',
		        iconAlign: 'top'
		    },{
		        text: '新增客户',
		        scale: 'large',
		        rowspan: 2, 
		        handler:onBtnClickHandler,
		        iconCls: 'menuDefault_32',
		        iconAlign: 'top'
		    },{
		        text: '客户通讯录',
		        scale: 'large',
		        rowspan: 2, 
		        handler:onBtnClickHandler,
		        iconCls: 'menuDefault_32',
		        iconAlign: 'top'
		    }]
		}]
	});
});

这样看起来就好很多,实现了业务与现实的分离,但是按钮多了,还是很郁闷,要写很多switch/case,

如何省去这些步骤呢?
我们发现他们的handler有一个共同点就是,都是负责切换显示页面的(也可能是弹出Window).
那么有这点相同就可以了,我直接就贴上来我的处理方法吧:
先写一个全局的对象,用于处理这些按钮如下:



Ext.namespace("Crm.Control.ConstEvent");
/**
 * 核心控制器
 * @type 
 */
Crm.Control.ConstEvent = {
	isInit:false,
	//初始化,主要是为该对象提供一个可以切换的容器,相当于Iframe
	init:function(panel){
		this.panel = panel;//当做IFrame来使
		this.isInit = true;
	},
	/**
	 * 切换主容器显示的内容函数(就是初始化传递进来的Panel)
	 * @param {} obj 一个字符串(具体是什么字符串请看下面的例子)
	 */
	changePanel:function(obj){
		//如果已经初始化
		if (this.isInit) {
			//由于时间关系,我这里就不判断是否已经存在相同的对象了,按理来讲应该判断一下传递进来的obj是否与
			//当前显示的obj是一个东西,如果是一个东西则return,至于如何判断,还是等下次再说吧
			try{
				this.panel.removeAll();//先移除先前加载进来的Panel(注意释放内存,此处省略)
			}catch(e){
				//EXTJS自带报表切换时会出现异常,具体原因不明,仅在IE下会出现此异常
			}finally{
				this.panel.add(eval(obj));//eval menuButton传递进来的对象(实际是个字符串具体看下面的例子)
				this.panel.doLayout();//调用布局函数,这样才会显示你刚刚添加进来的组件
			}
		}
	},
	/**
	 * 如果按钮指向的对象是window则使用此函数
	 * @param {} obj 一个字符串
	 */
	showWindow:function(obj){
		if (Ext.getCmp(obj.id)) {
			Ext.getCmp(obj.id).show();
			return;
		}
		if (this.isInit) {
			if(Ext.getCmp(obj.substring(4,obj.length-2))){
				Ext.getCmp(obj.substring(4,obj.length-2)).show();
				return;
			}
			eval(obj).show();
		}
	}
};


下面是所有MenuButton的父类:
Ext.namespace("Ext.ux.MenuButton.Button","Ext.ux.MenuButton.SplitButton");
Ext.ux.MenuButton.Button = Ext.extend(Ext.Button,{
	pageObject:"",//此按钮将要指向的那个模块(例如"new AAA.bbb.ccc()")
	isWindow:false,//此按钮指向的那个模块是否是一个window
	handler:function(btn){
		if (btn.isWindow) {
			Crm.Control.ConstEvent.showWindow(btn.pageObject);//如果按钮所包含的实体类是个window,则调用window展示函数
			return;
		}
		if (this.pageObject!="") {
			Crm.Control.ConstEvent.changePanel(btn.pageObject);//如果按钮所包含的实体类是个页面,则调用展示Panel的函数
		}
	}
});
Ext.reg("xmenubutton",Ext.ux.MenuButton.Button);
Ext.ux.MenuButton.SplitButton = Ext.extend(Ext.SplitButton,{
	pageObject:"",
	handler:function(btn){
		if (btn.isWindow) {
			Crm.Control.ConstEvent.showWindow(btn.pageObject);
			return;
		}
		if (this.pageObject!="") {
			Crm.Control.ConstEvent.changePanel(btn.pageObject);
		}
	}
});
Ext.reg("xsplitbutton",Ext.ux.MenuButton.SplitButton);

那么我们最上面的Menu就可以这么去写它
var panel = new Ext.Panel({
		renderTo:Ext.getBody(),
		border:false,
		tbar: [{
		    xtype: 'buttongroup',
		    columns: 6,
		    defaults:{xtype:"xmenubutton"},
		    title: '客户管理',
		    items: [{
                text: '客户信息',
                scale: 'large',
                rowspan: 2, 
                pageObject:"new Crm.Module.Client.BaseInfo()",//一个对象,用于传递给所谓的"核心控制器",就是上面的全局变量
                iconCls: 'menuDefault_32',
                iconAlign: 'top'
            },{
                text: '新增客户',
                scale: 'large',
                rowspan: 2, 
                isWindow:true,
                pageObject:"new Crm.Module.Client.NewClient()",
                iconCls: 'menuDefault_32',
                iconAlign: 'top'
            },{
                text: '客户通讯录',
                scale: 'large',
                rowspan: 2, 
                pageObject:"new Crm.Module.Client.AddList()",
                iconCls: 'menuDefault_32',
                iconAlign: 'top'
            }]
		}]
	});

这样一来,我们就可以少写很多代码了.

最近很忙,没时间来JE逛,所写的东西基本上是代码多,话少,写的比较乱....没办法...为了能好好的过年...老命豁出去了,对不住了.

2009年11月11日2:14:20 北京
3
0
分享到:
评论
3 楼 andy_ghg 2009-11-29  
cqhydz 写道
实话,后面哪个全局对象处理还不如第二种简结明了

嗯,有点,不过全局对象来处理的话弹性比较大
2 楼 cqhydz 2009-11-29  
实话,后面哪个全局对象处理还不如第二种简结明了
1 楼 energykey 2009-11-13  
朋友你QQ多少,我的QQ304275958验证:javaeye民工

我也是培训出来的,08年开始工作的。

我们经历很相似,加一个互相学习互相勉励。

我现在也在搞EXT,还没写过自己的组件水平。

相关推荐

Global site tag (gtag.js) - Google Analytics