论坛首页 Web前端技术论坛

EXT2.0 override方法的一个问题发现 及自我救赎 及等待救赎(非水)

浏览 1788 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (7) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-09-09   最后修改:2009-09-10
不知道怎么用标题来描述清除这个问题....  成吉思汗.....
被误导的兄弟,到别的帖子去散散心吧~~

-------------------------------------------------------------
EXT 2.0 是这样做组件扩展比如
Ext.grid.GridPanel = Ext.extend(Ext.Panel, {});

【背景】
项目的前台框架完全复制了EXT 2.0 的extend机制来建立自己的组件体系
下面代码中,My 可认为等同于 Ext

【问题代码】

--------------------类的代码----------------------------------
My.widgetA = My.extend(My.baseWidget,{
    ...

    testArray : [],                  //新的属性

    testFunc  : function(text){      //新的方法
        this.testArray.push(text);
    },

    ...
});


--------------------应用该类的页面的局部代码----------------------
var widget1 = new My.widgetA();
var widget2 = new My.widgetA();

widget1.testFunc("a");
widget1.testFunc("b");
debugger;
widget2.testFunc("c");
debugger;



【问题描述】

在第一个断点处,跟踪,发现 widget1.testArray = ["a","b"]
在第二个断点处,跟踪,发现 widget2.testArray 并不是预期中的 ["c"],而是 ["a","b","c"]

发现,若页面上存在N(N>1)个相同的组件时,如果新的扩展属性的类型是Array或Object,那么该属性在new的时候时创建的不是一个实例,而是一个引用。。。它们指向了同一个地方...

【自我救赎】
1、发现问题的第一感觉,太阳,抄都抄不对,,,

2、
  于是测试EXT自己的组件

  在ext-all-debug.js中 Ext.grid.GridPanel 定义里,增加testArray、testFunc,在EXT自带的 array-grid.html 中创建两个grid,如 局部代码 中一样的调用testFunc,结果发现问题相同!

3、
   在以前应用EXT时,曾发现 Ext.apply在复制对象的时候,如果对象的属性是Object,那么复制的新对象中,该属性是一个引用而不是一个实例。
   于是怀疑是不是EXT的 extend、override方法中复制的不彻底,EXT的override 方法:
        override : function(origclass, overrides){
            if(overrides){
                var p = origclass.prototype;
                for(var method in overrides){
                    p[method] = overrides[method];
                }
            }
        },
  


做了一个简单的修改后,override 方法如下:
        override : function(origclass, overrides){
            if(overrides){
                var p = origclass.prototype;

                for(var method in overrides){
                    if(overrides[method] instanceof Array){
                        p[method] = [].concat(overrides[method]);
                    }
                    else{
                        p[method] = overrides[method];
                    }
                }
            }
        },

再次测试 array-grid.html,发现问题木有啦!

4、测试过程中,发现了另外一个解决办法,
--------------------类的代码----------------------------------
My.widgetA = My.extend(My.baseWidget,{
    ...

    //testArray : [],                  //新的属性   不明确定义 testArray属性

    testFunc  : function(text){      //新的方法
        this.testArray = this.testArray ||[];    //用时再初始化
        this.testArray.push(text);
    },

    ...
});



【后记及发帖目的】

项目一直采用EXT2.0做前台框架,并没有随EXT版本升级,力求稳定
所以不知道同样的问题,在3.0里面是不是还算问题

没有看到类似的问题,不知道是不是有达人提出并解决过类似的问题
有知道的兄弟,跟帖发链接啊

另外本人比较懒也比较笨 能解决问题 走走水路也无妨
所以宁愿多尝试 在可能的地方用可能的方式多测试 能解决就成
不愿从技术的根本去用理论和系统的方法来求证...
所以很多时候 知其然不知其所以然  -_-||

在调试这个问题的时候,是做了决心,看了下EXT的extend 方法的,结果当然很晕
JE上有篇帖好像是讲这个的 记得当时也很晕
所以对自己说 这个有牛人做出来就可以啦 我们只用


----------------------------------------------------------
                    H  E  L  P !!!
----------------------------------------------------------

1、到底是不是override实现的问题
2、对于属性类型为Array,我的解决方法有没有什么问题和隐患
3、如果属性类型是Object,该如何解决

我尝试了如下代码,结果错误抛在Ext.grid.GridPanel的onRender方法中的var view = this.getView();
执行后跟踪,发现view 是一个空对象,猜测和我的代码实现有关:
        override : function(origclass, overrides){
            if(overrides){
                var p = origclass.prototype;

                for(var method in overrides){
                    if(overrides[method] instanceof Array){
                        p[method] = [].concat(overrides[method]);
                    }else if(typeof overrides[method] =='object'){
                        p[method] = {};
                        Ext.apply(p[method] , overrides[method]);
                    }
                    else{
                        p[method] = overrides[method];
                    }
                }
            }
        },
论坛首页 Web前端技术版

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