EXTJS组件化(四)---减少你的代码
代码量,BUG和维护成本是水涨船高的关系,这点应该不能被否认的,因此如何的减少代码的编写量成了很多人努力的一个方向.当然,这肯定不是为了偷懒
减少代码量的编写自然是对象的重复利用,以前所写的组件化,它确实是一个独立的对象,可以拿来重用,但是,写到最后会发现,这些组件往往只是使用了一次而已,而且根据需求的不同会发现这个组件根本就无法被重新使用了(定制性太强)
于是,我们就需要拆分这个组件,看看这些组件中都有哪些东西是经常被用到的.
比如导航栏,一排导航十多个按钮,他们都是按钮,但是他们的handler虽然都是切换显示页面,但是每个按钮所负责的页面却是不同的,曾经有人问过,我是不是要为每一个按钮都编写一个handler处理函数?
这样写起来,一旦导航多了,就比较麻烦了,代码显得很乱,不好维护,怎么办?
也许有人会这么去写它:
这样看起来就好很多,实现了业务与现实的分离,但是按钮多了,还是很郁闷,要写很多switch/case,
如何省去这些步骤呢?
我们发现他们的handler有一个共同点就是,都是负责切换显示页面的(也可能是弹出Window).
那么有这点相同就可以了,我直接就贴上来我的处理方法吧:
先写一个全局的对象,用于处理这些按钮如下:
下面是所有MenuButton的父类:
那么我们最上面的Menu就可以这么去写它
这样一来,我们就可以少写很多代码了.
最近很忙,没时间来JE逛,所写的东西基本上是代码多,话少,写的比较乱....没办法...为了能好好的过年...老命豁出去了,对不住了.
减少代码量的编写自然是对象的重复利用,以前所写的组件化,它确实是一个独立的对象,可以拿来重用,但是,写到最后会发现,这些组件往往只是使用了一次而已,而且根据需求的不同会发现这个组件根本就无法被重新使用了(定制性太强)
于是,我们就需要拆分这个组件,看看这些组件中都有哪些东西是经常被用到的.
比如导航栏,一排导航十多个按钮,他们都是按钮,但是他们的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逛,所写的东西基本上是代码多,话少,写的比较乱....没办法...为了能好好的过年...老命豁出去了,对不住了.