|
兼容性 |
Ext类不可能提供浏览器的兼容具体的处理。因为兼容处理只能落实具体的方法中。它提供了一组属于用来判断用户使用的浏览器、操作系统等,在需要兼容处理的地方只要直接调用这些属于就可以进行判断再来进行相关的兼容处理。 isAir、isBorderBox、isGecko、isIE、isIE7、isLinux、isMac、isOpera、isSafari、isStrict、isWindows这些属性是Ext类提供的兼容方面的属性。这些属性大部分是从navigator.userAgent来获取到的。 |
|
重用性 |
Ext类中提供二组关于代码重用的方法。 第一组是apply,applyIf函数,它实现把对象内部的方法或属于直接复制到另外一个对象。这是最基础的继承方式。 第二组是extend,override函数,这一组是高级继承方式,它不仅仅是把一个函数的方法和属性复制到另外一个函数的原型中去,它还要建立其两者之间的父子链的关系。 |
|
组件入口 |
Ext类中提供了组件的入口getCmp(id)函数。 每个组件都有id属性,只要定义时给定其值,之后在任何地方都通过Ext.getCmp(id)来获得该对象的引用。这为全局管理组件提供了方便。其是Ext.ComponentMgr.get的简化。这一部分内部在后面的章节会详细地讲解。 |
|
元素入口 |
所有Js类库的最终目的都是对于Dom元素进行操作。Ext对Dom元素进行封装为Element元素。但是在Ext类也提供了很多这方面的方法。 1、事件处理。Ext类提供了addBehaviors和onReady两个事件处理函数。一个是监听DomReady,一个是给所指定的元素注册事件监听。 2、获取元素。fly、get是根据参数获取元素的两种不种的处理方式。getBody、getDoc则是获到指定Dom的元素。而getDom是从封装的Element元素中获取其原始的Dom元素。 3、查询Dom树。query、select是两个CSS语法兼容的Dom query方法。通过这两个方法能方便地用Dom树中找到元素。 4、删除元素:removeNode、destroy是为了删除元素,释放内存而给出的。destroy还能删除组件。 |
|
实用方法 |
Ext类提供如下四类的实用方法: 1、type类型。Js的typeof只能判断最原始的类型,如Array是返回是Function,而new Array()则是数组。对于dom元素不能深入去判断其节点类型。Ext.type则指代了更为精准的判断。它还提供了isArray、isDate等类型判断函数。 2、命名空间。Ext.namespace()函数能动态生成指定的命名空间。 3、格式转换。Ext类提供了decode、encode 方法实现string和json对象之间的相互转换。还提供了urlDecode、urlEncode方法来进行查询字符串和JS对象进行的相互转换。在3.4节中分析。 4、其它:在new RegExp时,对于正则的字符串中的特殊符号要进行特殊的处理,Ext.escapeRe 就是进行这样的操作。 Ext.each是集合的元素都进行相类似的操作,如Fn的操作。这是很常用的函数。 |
表3-1 Ext类的功能归总表
在上表中,我们把Ext类提供的功能分成了五部分。下面小节就是对这几部分进行展开来进行分析。兼容性的部分的代码简单,下面就不展开来,读者可以能对着Ext类的源码自行分析。组件入口部分,其内容众多且复杂,后面的几个章节会对其进行详细的分析。
Ext.apply = function(o, c, defaults){ 

if(defaults)...{ Ext.apply(o, defaults); } 
if(o && c && typeof c == 'object')...{
for(var p in c)...{ o[p] = c[p]; }
}
return o; 
点击展开
extend : function(){
//io,oc是采用了闭包函数的特点,减少了函数的变量的定义,只有内部能访问。 

var io = function(o)...{ for(var m in o){this[m] = o[m];} };①
var oc = Object.prototype.constructor;
//sb,sp是函数类型(即类),overrides是对象类型 
return function(sb, sp, overrides)...{ ②
//说明只传入了两个参数。省去sb,sb函数是通过本函数新生成的 
if(typeof sp == 'object')...{ ③
overrides = sp;
sp = sb;
//如果overrides中含有constructor方法时,它就是sb子类的构造函数。
//否则就新建一个构造函数,传入参数调用其父类的构造函数。
sb = overrides.constructor != oc ?
overrides.constructor : function()...{sp.apply(this, arguments);};
}
var F = function()...{}, sbp, spp = sp.prototype;
F.prototype = spp;
//采用new F()新建一个含有所有sp.prototype中的功能的对象。
//这里做是为了改变sb.prototype中不会改为sp.prototype
sbp = sb.prototype = new F(); ④
//标识sb的实例对象中的constructor为sb函数。
sbp.constructor=sb;
//通过这里的实现,我们就可以类方法的形式去调用其superclass中的方法。
sb.superclass=spp; ⑤
//改变父类实例对象中的constructor标识,使其指向自身的构建函数
if(spp.constructor == oc)...{ spp.constructor=sp; } ⑥
//给sb注册一个类方法override.
sb.override = function(o)...{Ext.override(sb, o); };
//sb实例对象中override方法
sbp.override = io; ⑦
//把overrides中的方法拷到sb的prototype中,使实例拥有该方法
Ext.override(sb, overrides); ⑧
//为子类加上一个类方法:extend
sb.extend = function(o)...{Ext.extend(sb, o);}; ⑨
return sb;
};
}() ⑩
var myclass=function(config){
.. .. ..
myclass.superclass.constructor.call(this, this.meta);//这里是把参数传到父类中构建方法中
… …
} 

Ext.extend(myclass,supclass,...{//一些增加的方法或属性});
var superclass=function(sp){ 

var s=function()...{ return arguments.callee.superclass; }
s.superclass=sp;
return s;};
点击展开示例
var Animal = function() {
alert("this is Animal constructor");
this.name = 'animal';
this.age = 7;
}; 
Animal.prototype.getAge = function() ...{
alert(this.name+"'age is "+this.age);
}; 
Animal.prototype.getName = function() ...{
alert("this is the animal Name!");
}; 
var Cat = Ext.extend(Animal, ...{
name : 'cat',
age : 5, 
constructor : function() ...{
alert("this is Cat constructor");
this.superclass().constructor(arguments);
}, 
getAge : function() ...{
alert(this.name + "'age is " + this.age);
this.superclass().getAge();
}
}); 
var homeCat = function() ...{
alert("this is homeCat constructor");
this.superclass().constructor(arguments);
}; 
Ext.extend(homeCat, Cat, ...{
name : 'homeCat',
age : 3, 
getAge : function() ...{
this.superclass().getAge();
}
});
var myCat = new homeCat();
myCat.getAge();
点击展开示例
var superclass = function(sp) { 
var s = function() ...{
var name = (s.caller || ...{}).name;
var len = arguments.length, t = this;
var supper = arguments.callee.superclass;
if (!name) 
for (var n in t) ...{
if (t[n] == s.caller) ...{ name = n; break; }
} 
if (len > 0 && name) ...{
var callArgs = Array.prototype.slice.call(arguments, 0);
Array.prototype.splice.apply(callArgs, [0, 1]);
return supper[name](callArgs);
}
return supper;
}
s.superclass = sp;
return s;
};