欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Extjs學(xué)習(xí)筆記之八 繼承和事件基礎(chǔ)

 更新時間:2010年01月08日 22:27:20   作者:  
只有有了事件,頁面才能真正的“活”起來。Extjs的事件也是經(jīng)過良好封裝的,對于事件的處理都由Ext.uitl.Observable類提供接口。
這里接口的意思是Observable實際上起了一個抽象類的作用,Extjs中有大量的組件都是繼承自這個類的。這個類提供了一些基本的方法比如addEvents,addlistener,fireEvent等等。

本文暫時不介紹如何使用extjs的組件響應(yīng)事件,而是介紹Extjs的事件的一些實現(xiàn)原理。整個Extjs框架都是以一種面向?qū)ο蟮姆绞介_發(fā)的,所以理解Javascript中的繼承也很重要。我前面的一篇文章 補點基礎(chǔ):Javascript中的類和閉包 也是為這篇做準(zhǔn)備。另外,博客園內(nèi)還有一個寫的很好的系列 JavaScript繼承詳解. 他主要是根據(jù)Douglas Crockford的兩篇文章寫的。 其實實現(xiàn)繼承的原理都差不多,大家可以參考閱讀。

Extjs實現(xiàn)繼承的函數(shù)是一個很核心的函數(shù)Ext.extend,extend方法有兩個重構(gòu)版本,第一個接受兩個參數(shù),第一個是extend( Function superclass, Object overrides ) ,第二個是extend( Function subclass, Function superclass,Object overrides ) : Function,第二個版本是在subclass的基礎(chǔ)上。superclass就是超類的構(gòu)造函數(shù),overrides是一個對象,里邊的屬性就是要覆蓋父類的屬性。繼承了父類的子類具有父類的prototype中的所有方法。并且子類可以覆蓋父類的方法(override),更進一步,子類的每個對象也可以覆蓋父類的方法。其實我覺得這個函數(shù)沒什么作用,修改prototype的效果是等效的,當(dāng)然,extjs的目的肯定是要把prototype這個神奇的東西完全屏蔽起來,使程序員能夠像處理其他語言一樣來處理Javascript。當(dāng)然,即使如此,它的繼承和一般的繼承還是有些不同的,下面先看個例子,準(zhǔn)備好一個Person類
復(fù)制代碼 代碼如下:

Person = function(name) {
this.name = name;
this.fn = function() { alert('I am a person') };
}
Person.prototype.print=function(){ alert('I am a person');}
Person.prototype.showAge = function() { alert('I am older than 0'); }
Person.prototype.showName = function() { alert('Show Name:'+this.name) };
var per = new Person('Tom');
per.showName();子類:Student = function(id) {
this.id = id;
}
Student.prototype.showID = function() { alert(this.id); } //子類的方法

繼承:
Ext.extend(Student, Person);
stu.showName(); !!沒有結(jié)果!stu沒有name的定義stu.fn(); !!沒有結(jié)果 stu.showID(); !!!還是沒有結(jié)果到此我們已經(jīng)發(fā)現(xiàn)了一些不同:在父類的構(gòu)造函數(shù)中的內(nèi)容是不會繼承的,父類的構(gòu)造函數(shù)不會被調(diào)用,子類(prototype中)已有的方法也會丟失!繼續(xù)看下去,將Ext.extend下面的代碼替換成:
復(fù)制代碼 代碼如下:

var stu = new Student('01');
Student.override({ print: function() { alert('I am a student'); } });
stu.override({ print: function() { alert('I am a bad student,but I won\'t affect others'); } });
stu.print();
stu.showAge();
var stu2 = new Student();
stu2.print();

這里的函數(shù)都能夠按預(yù)期輸出,showAge是執(zhí)行的父類的方法,stu.print是執(zhí)行的stu.override中指定的方法,而stu2執(zhí)行的是Student.override中指定的方法。到這里,我們已經(jīng)大概能猜出extend是如何實現(xiàn)的了。下面看它真正的源代碼,這個方法位于Ext.js中,代碼和注釋如下:extend : function(){
復(fù)制代碼 代碼如下:

// inline overrides
var io = function(o){ //注意這個方法的this,僅看這里并不知道這個this是什么,下面這個io會被賦值給sbp.override,也就是子類的prototype
for(var m in o){ //從而每個子類的對象的override都會指向這個方法,如果子類對象調(diào)用了override,那么這個this就是子類的對象了。也就是
this[m] = o[m]; //上面的例子中stu.override表現(xiàn)出來的效果,僅對當(dāng)前對象有效。從這里可以看出,override不僅僅是傳統(tǒng)意義上的覆蓋,完全也可以
} //用來添加新方法。
};
var oc = Object.prototype.constructor;

return function(sb, sp, overrides){
if(Ext.isObject(sp)){ //是在檢測當(dāng)前使用的是哪個版本的重構(gòu)函數(shù)。如果sp實際上是overrides,就做些替換工作,讓變量的實際意義和名稱相符合。
overrides = sp;
sp = sb;
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; //這個沒看懂……
}
var F = function(){},
sbp,
spp = sp.prototype;

F.prototype = spp; //F是父類的一個“干凈”拷貝,所謂干凈,是指它不會把父類中在構(gòu)造函數(shù)內(nèi)部定義的屬性帶過來。 //例如 Person=function() // {this.privateFn=new function{ some code goes here}} //那么這個privateFn對子類是不可見的,所以在構(gòu)造函數(shù)中利用this定義的屬性都相當(dāng)于是類的私有變量。
sbp = sb.prototype = new F(); //將子類的prototype設(shè)置為父類的prototype,繼承的核心步驟。 sbp.constructor=sb; //設(shè)置正確的構(gòu)造函數(shù)指向,見 JavaScript繼承詳解
sb.superclass=spp; //設(shè)置父類
if(spp.constructor == oc){ //沒看懂……,這個是干嘛用的?望高人指點
spp.constructor=sp;
}
sb.override = function(o){ //子類的重寫方法,這個重寫方法是函數(shù)的重寫方法。它修改的是prototype。
Ext.override(sb, o); //見最后。
};
sbp.superclass = sbp.supr = (function(){ //設(shè)置原型的父類
return spp;
});
sbp.override = io; //給子類的prototype提供override方法,這樣單個實體也可以覆蓋,它修改的是實體對象。注意和上面的sb的override區(qū)分。
Ext.override(sb, overrides); //重寫
sb.extend = function(o){return Ext.extend(sb, o);}; //給子類提供extend方法,以實現(xiàn)多重繼承
return sb; //返回子類。
};
}();

下面是Ext.override的代碼,比較明了的,和那個inline override相比,它就是修改的prototype:override :
復(fù)制代碼 代碼如下:

function(origclass, overrides){
if(overrides){
var p = origclass.prototype;
Ext.apply(p, overrides);
if(Ext.isIE && overrides.hasOwnProperty('toString')){ // 這個是什么?IE的特殊點?
p.toString = overrides.toString;
}
}
}

現(xiàn)在就可以開始正式介紹Extjs的事件模型了。和其他語言事件類似,首先要為一個類定義事件,其他語言(例如C#)的事件一般有一個專門的event類型,event類型實際上可以看作是委托的數(shù)組,當(dāng)然委托實際上是函數(shù),添加時間監(jiān)聽器(listener),就是想委托數(shù)組中添加委托(函數(shù)),所謂觸發(fā)事件就是把數(shù)組中的函數(shù)統(tǒng)統(tǒng)執(zhí)行一遍。Javascript也是類似的,只是Javascript的函數(shù)比那些語言強大靈活的多,因此也不需要什么event類型了。Javascript的事件看起來就像一個字符串(它內(nèi)部應(yīng)該也是保留了一個數(shù)組的),可以通過Observale.addEvents方法添加事件,通過Observale.fireEvent觸發(fā)事件,通過Observale.addListner增加事件監(jiān)聽器。下面舉一個沒什么意義卻能說明問題的例子。
復(fù)制代碼 代碼如下:

Odder = function(min, max) {
this.min = min;
this.max = max;
this.addEvents('onFindOdd');
}
Ext.extend(Odder, Ext.util.Observable, { run:
function() {
for (var i = this.min; i < this.max; i++) {
if (i % 2 != 0) {
this.fireEvent('onFindOdd',i);
}
}
}
});
var p = new Odder(4, 8);
p.addListener('onFindOdd',function(n){alert(n);});
p.run();

Odder是這么一個類,它通過一個構(gòu)造函數(shù)傳入一個范圍,然后尋找這個范圍內(nèi)的所有奇數(shù),每找到一個就觸發(fā)一個事件。我給它加一個事件處理程序,把它找到的奇數(shù)alert出來。 要注意,這里的事件處理程序的參數(shù)只能靠程序員自己保持一致,它不像委托那樣強類型。

注意,我沒有采用官網(wǎng)上的例子:
復(fù)制代碼 代碼如下:

Employee = Ext.extend(Ext.util.Observable, {
constructor: function(config){
this.name = config.name;
this.addEvents({
"fired" : true,
"quit" : true
});

// Copy configured listeners into *this* object so that the base class's
// constructor will add them.
this.listeners = config.listeners;

// Call our superclass constructor to complete construction process.
Employee.superclass.constructor.call(config)
}
});This could then be used like this:
var newEmployee = new Employee({
name: employeeName,
listeners: {
quit: function() {
// By default, "this" will be the object that fired the event.
alert(this.name + " has quit!");
}
}
});

我覺得官網(wǎng)上的例子內(nèi)部還有文章,它的重載項中包含了constructor屬性,給人的感覺是是重載了父類的構(gòu)造函數(shù),然后子類就會調(diào)用這個構(gòu)造函數(shù)來創(chuàng)建,其實不是的,它改變了Javascript本身的行為,這個就和我上面標(biāo)注的沒有看懂的那幾句代碼有關(guān)系。下回再討論。

相關(guān)文章

  • Extjs中常用表單介紹與應(yīng)用

    Extjs中常用表單介紹與應(yīng)用

    知道表單面板如何創(chuàng)建 了解表單面板中xtype的類型的應(yīng)用 知道表單面板如何驗證,綁定,取值 綜合應(yīng)用表單面板(玩轉(zhuǎn)它)
    2010-06-06
  • extjs 列表框(multiselect)的動態(tài)添加列表項的方法

    extjs 列表框(multiselect)的動態(tài)添加列表項的方法

    最近公司一個項目,因為要使用div模擬的窗口,因為久聞extjs的大名,因此就想在項目中使用一下.首先下載了multiselect的extjs3.0 demo.看到的代碼這里我就不粘貼了.
    2009-07-07
  • ANT 壓縮(去掉空格/注釋)JS文件可提高js運行速度

    ANT 壓縮(去掉空格/注釋)JS文件可提高js運行速度

    在解決這個有很多優(yōu)化方法,今天來說其中一種,那就是在Ant腳本打包的時候,把js中空格、注釋去掉、以及合并,合并今天不說了,還未實現(xiàn)這個,在研究中
    2013-04-04
  • ExtJs 3.1 XmlTreeLoader Example Error

    ExtJs 3.1 XmlTreeLoader Example Error

    ExtJs 3.1的XmlTreeLoader例子折騰了我近一個下午加晚上,官方的例子沒有問題,可以加載xml的數(shù)據(jù),本地IIS死活不行
    2010-02-02
  • ExtJS Window 最小化的一種方法

    ExtJS Window 最小化的一種方法

    ExtJS 中Window的窗口最大化只需將maximizable屬性設(shè)置為true即可,點擊最大化按鈕就可以將窗體最大化,最小化的操作類似將minimizable設(shè)置為true,即可以看到窗體的最小化按鈕,但是點擊此按鈕并不會出發(fā)任何操作,Ext沒有為窗口預(yù)設(shè)最小化的任何操作,需要自己自定義最小化功能。
    2009-11-11
  • Extjs4 GridPanel 的幾種樣式使用介紹

    Extjs4 GridPanel 的幾種樣式使用介紹

    接下來為大家介紹下GridPanel的幾種樣式及選擇模式分類介紹,感興趣的朋友可以參考下哈
    2013-04-04
  • ExtJS Grid使用SimpleStore、多選框的方法

    ExtJS Grid使用SimpleStore、多選框的方法

    ExtJS 中Grid使用SimpleStore、多選框的方法,需要的朋友可以參考下。
    2009-11-11
  • ExtJs的Date格式字符代碼

    ExtJs的Date格式字符代碼

    首先簡單介紹一下ExtJs中的Date基本上就是PHP date函數(shù)的一個子集,表征了一個日期對象。廢話到此為止。
    2010-12-12
  • ExtJS 2.0實用簡明教程 之獲得ExtJS

    ExtJS 2.0實用簡明教程 之獲得ExtJS

    要使用ExtJS,那么首先要得到ExtJS庫文件,該框架是一個開源的,可以直接從官方網(wǎng)站下載
    2009-04-04
  • Extjs中通過Tree加載右側(cè)TabPanel具體實現(xiàn)

    Extjs中通過Tree加載右側(cè)TabPanel具體實現(xiàn)

    用Extjs4.1來做界面,有關(guān)Extjs4.1資料在網(wǎng)上也相對來說較少,下面是具體的實現(xiàn)代碼1.左側(cè)的功能樹2.需要打開的對應(yīng)的view,有類似需求的朋友可以參考下哈
    2013-05-05

最新評論