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


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

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

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

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

Js代码  收藏代码
  1. Ext.onReady(function(){  
  2.     var panel = new Ext.Panel({  
  3.         renderTo:Ext.getBody(),  
  4.         border:false,  
  5.         tbar: [{  
  6.             xtype: 'buttongroup',  
  7.             columns: 6,  
  8.             title: '客户管理',  
  9. //          defaults:{xtype:"xmenubutton"},  
  10.             items: [{  
  11.                 text: '客户信息',  
  12.                 scale: 'large',  
  13.                 rowspan: 2,   
  14.                 handler:function(){  
  15.                     //TODO 处理  
  16.                 },  
  17.                 iconCls: 'menuDefault_32',  
  18.                 iconAlign: 'top'  
  19.             },{  
  20.                 text: '新增客户',  
  21.                 scale: 'large',  
  22.                 rowspan: 2,   
  23.                 handler:function(){  
  24.                     //TODO 处理  
  25.                 },  
  26.                 iconCls: 'menuDefault_32',  
  27.                 iconAlign: 'top'  
  28.             },{  
  29.                 text: '客户通讯录',  
  30.                 scale: 'large',  
  31.                 rowspan: 2,   
  32.                 handler:function(){  
  33.                     //TODO 处理  
  34.                 },  
  35.                 iconCls: 'menuDefault_32',  
  36.                 iconAlign: 'top'  
  37.             }]  
  38.         }]  
  39.     });  
  40. });  

这样写起来,一旦导航多了,就比较麻烦了,代码显得很乱,不好维护,怎么办?
也许有人会这么去写它:
Js代码  收藏代码
  1. Ext.onReady(function(){  
  2.     function onBtnClickHandler(btn){  
  3.         switch (btn.text){  
  4.             case "客户信息":  
  5.                 //TODO  
  6.                 alert("aaa");  
  7.                 break;  
  8.             case "新增客户":  
  9.                 //TODO  
  10.                 break;  
  11.             case "客户通讯录":  
  12.                 //TODO  
  13.                 break;  
  14.         }  
  15.     }  
  16.     var panel = new Ext.Panel({  
  17.         renderTo:Ext.getBody(),  
  18.         border:false,  
  19.         tbar: [{  
  20.             xtype: 'buttongroup',  
  21.             columns: 6,  
  22.             title: '客户管理',  
  23.             items: [{  
  24.                 text: '客户信息',  
  25.                 scale: 'large',  
  26.                 rowspan: 2,   
  27.                 handler:onBtnClickHandler,  
  28.                 iconCls: 'menuDefault_32',  
  29.                 iconAlign: 'top'  
  30.             },{  
  31.                 text: '新增客户',  
  32.                 scale: 'large',  
  33.                 rowspan: 2,   
  34.                 handler:onBtnClickHandler,  
  35.                 iconCls: 'menuDefault_32',  
  36.                 iconAlign: 'top'  
  37.             },{  
  38.                 text: '客户通讯录',  
  39.                 scale: 'large',  
  40.                 rowspan: 2,   
  41.                 handler:onBtnClickHandler,  
  42.                 iconCls: 'menuDefault_32',  
  43.                 iconAlign: 'top'  
  44.             }]  
  45.         }]  
  46.     });  
  47. });  

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

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


Js代码  收藏代码
  1. Ext.namespace("Crm.Control.ConstEvent");  
  2. /** 
  3.  * 核心控制器 
  4.  * @type  
  5.  */  
  6. Crm.Control.ConstEvent = {  
  7.     isInit:false,  
  8.     //初始化,主要是为该对象提供一个可以切换的容器,相当于Iframe  
  9.     init:function(panel){  
  10.         this.panel = panel;//当做IFrame来使  
  11.         this.isInit = true;  
  12.     },  
  13.     /** 
  14.      * 切换主容器显示的内容函数(就是初始化传递进来的Panel) 
  15.      * @param {} obj 一个字符串(具体是什么字符串请看下面的例子) 
  16.      */  
  17.     changePanel:function(obj){  
  18.         //如果已经初始化  
  19.         if (this.isInit) {  
  20.             //由于时间关系,我这里就不判断是否已经存在相同的对象了,按理来讲应该判断一下传递进来的obj是否与  
  21.             //当前显示的obj是一个东西,如果是一个东西则return,至于如何判断,还是等下次再说吧  
  22.             try{  
  23.                 this.panel.removeAll();//先移除先前加载进来的Panel(注意释放内存,此处省略)  
  24.             }catch(e){  
  25.                 //EXTJS自带报表切换时会出现异常,具体原因不明,仅在IE下会出现此异常  
  26.             }finally{  
  27.                 this.panel.add(eval(obj));//eval menuButton传递进来的对象(实际是个字符串具体看下面的例子)  
  28.                 this.panel.doLayout();//调用布局函数,这样才会显示你刚刚添加进来的组件  
  29.             }  
  30.         }  
  31.     },  
  32.     /** 
  33.      * 如果按钮指向的对象是window则使用此函数 
  34.      * @param {} obj 一个字符串 
  35.      */  
  36.     showWindow:function(obj){  
  37.         if (Ext.getCmp(obj.id)) {  
  38.             Ext.getCmp(obj.id).show();  
  39.             return;  
  40.         }  
  41.         if (this.isInit) {  
  42.             if(Ext.getCmp(obj.substring(4,obj.length-2))){  
  43.                 Ext.getCmp(obj.substring(4,obj.length-2)).show();  
  44.                 return;  
  45.             }  
  46.             eval(obj).show();  
  47.         }  
  48.     }  
  49. };  


下面是所有MenuButton的父类:
Js代码  收藏代码
  1. Ext.namespace("Ext.ux.MenuButton.Button","Ext.ux.MenuButton.SplitButton");  
  2. Ext.ux.MenuButton.Button = Ext.extend(Ext.Button,{  
  3.     pageObject:"",//此按钮将要指向的那个模块(例如"new AAA.bbb.ccc()")  
  4.     isWindow:false,//此按钮指向的那个模块是否是一个window  
  5.     handler:function(btn){  
  6.         if (btn.isWindow) {  
  7.             Crm.Control.ConstEvent.showWindow(btn.pageObject);//如果按钮所包含的实体类是个window,则调用window展示函数  
  8.             return;  
  9.         }  
  10.         if (this.pageObject!="") {  
  11.             Crm.Control.ConstEvent.changePanel(btn.pageObject);//如果按钮所包含的实体类是个页面,则调用展示Panel的函数  
  12.         }  
  13.     }  
  14. });  
  15. Ext.reg("xmenubutton",Ext.ux.MenuButton.Button);  
  16. Ext.ux.MenuButton.SplitButton = Ext.extend(Ext.SplitButton,{  
  17.     pageObject:"",  
  18.     handler:function(btn){  
  19.         if (btn.isWindow) {  
  20.             Crm.Control.ConstEvent.showWindow(btn.pageObject);  
  21.             return;  
  22.         }  
  23.         if (this.pageObject!="") {  
  24.             Crm.Control.ConstEvent.changePanel(btn.pageObject);  
  25.         }  
  26.     }  
  27. });  
  28. Ext.reg("xsplitbutton",Ext.ux.MenuButton.SplitButton);  

那么我们最上面的Menu就可以这么去写它
Js代码  收藏代码
  1. var panel = new Ext.Panel({  
  2.         renderTo:Ext.getBody(),  
  3.         border:false,  
  4.         tbar: [{  
  5.             xtype: 'buttongroup',  
  6.             columns: 6,  
  7.             defaults:{xtype:"xmenubutton"},  
  8.             title: '客户管理',  
  9.             items: [{  
  10.                 text: '客户信息',  
  11.                 scale: 'large',  
  12.                 rowspan: 2,   
  13.                 pageObject:"new Crm.Module.Client.BaseInfo()",//一个对象,用于传递给所谓的"核心控制器",就是上面的全局变量  
  14.                 iconCls: 'menuDefault_32',  
  15.                 iconAlign: 'top'  
  16.             },{  
  17.                 text: '新增客户',  
  18.                 scale: 'large',  
  19.                 rowspan: 2,   
  20.                 isWindow:true,  
  21.                 pageObject:"new Crm.Module.Client.NewClient()",  
  22.                 iconCls: 'menuDefault_32',  
  23.                 iconAlign: 'top'  
  24.             },{  
  25.                 text: '客户通讯录',  
  26.                 scale: 'large',  
  27.                 rowspan: 2,   
  28.                 pageObject:"new Crm.Module.Client.AddList()",  
  29.                 iconCls: 'menuDefault_32',  
  30.                 iconAlign: 'top'  
  31.             }]  
  32.         }]  
  33.     });  

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

最近很忙,没时间来JE逛,所写的东西基本上是代码多,话少,写的比较乱....没办法...为了能好好的过年...老命豁出去了,对不住了.
原文地址:https://www.cnblogs.com/sunscheung/p/4839407.html