ST2 採用跟Ext JS 4一樣的類系統。這使得我們可以很輕鬆地在JavaScript中創建或繼承新的類。類系統提供了繼承,依賴加載,mixin,強大的配置選項等內容。
簡單來說,類是一個擁有一些屬性和方法的對象。例如:定義一個動物類,定義其名稱和功能,使得它能說話,我們只需這樣做:
1
2
3
4
5
6
7
8
9
|
Ext.define( 'Animal' ,
{ config:
{ name:
null }, speak:
function ()
{ alert( 'grunt' ); } }); |
這樣我們就定義了一個動物類,每個動物可以有一個名稱,並可以說話。要創建一個新的的動物,我們只需這樣:
1
2
3
4
|
var
bob = Ext.create( 'Animal' ,
{ name:
'Bob' }); bob.speak();
//alerts
'grunt' |
在這裏,我們創建了一個名爲Bob的動物,並命令它說話。現在,我們已經定義了一個類和並創建了一個實例,但我們不知道鮑勃是什麼物種,所以讓我們定義一個人類的作爲動物類的子類:
1
2
3
4
5
6
7
|
Ext.define( 'Human' ,
{ extend:
'Animal' , speak:
function ()
{ alert( this .getName()); } }); |
現在我們已經從動物類繼承了一個新的的人類,因此人類獲得其所有的方法和配置。實際上,我們重寫了說話的方法,因爲大多數人有足夠的智慧,說他們的名字,而不是咕嚕咕嚕地叫。現在,我們創建一個名爲Bob的人,並讓他說話:
1
2
3
4
5
|
var
bob = Ext.create( 'Human' ,
{ name:
'Bob' }); bob.speak();
//alerts
'Bob' |
你應該也注意到了上面的代碼中使用了getName方法,然而我們並沒有定義動物類的getName方法。那它來自哪裏?答案是:框架自動幫每一個配置項添加了以下方法:
- 一個getter方法 - 如getName就是返回name的當前值。
- 一個setter方法 - 如getName就是爲name設置一個新值。
- an applier function - applyName() in this case - which is called by the setter and lets you run a function when a configuration changes
getter和setter都是自動生成的,建議大家使用它們來存取類裏面的數據。ST的每一個組件都使用了getter和setter的模式,這意味着如果我們知道一個配置項,也就知道如何獲取和設置它的值了。
這也讓你的的代碼更整潔。舉個例子:如果你想在改變Bob的名字時詢問用戶。就可以定義applyName方法,它會被自動調用:
1
2
3
4
5
6
7
|
Ext.define( 'Human' ,
{ extend:
'Animal' , applyName:
function (newName,
oldName) { return
confirm( 'Are
you sure you want to change name to '
+ newName + '?' ); } }); |
我們用瀏覽器內建的confirm方法彈出了一個確認操作的對話框。如果applier方法返回的是false,那name的值將不會發生改變。
1
2
3
4
5
6
7
8
9
|
var
bob = Ext.create( 'Person' ,
{ name:
'Bob' }); bob.setName( 'Fred' );
//opens
a confirm box, but we click No bob.speak();
//still
alerts 'Bob' 我們已經學習了類系統的這些內容: |
- 用Ext.define來定義新的類。
- 用Ext.create來創建對象實例。例如:Ext.create('SomeClass', {some: 'configuration'})
- 用"extend"來繼承擴展類。
- 使用系統自動生成的getter和setter方法,這會讓代碼更整潔。
現在,你已經學會如何定義和使用一個類。但類系統的內容遠遠不只這些。
依賴與動態加載
大多數時候,類之間都存在着依賴。我們可以使用"requires"關鍵字來引入一個被依賴的類。人類依賴動物類並擴展動物類,這種情況下並不需要特殊的說明,用"extend"就已經表明了這種依賴關係。
1
2
3
4
5
6
7
8
9
|
Ext.define( 'Human' ,
{ extend:
'Animal' , requires:
'Ext.MessageBox' , speak:
function ()
{ Ext.Msg.alert() } }); |
當你像這樣定義一個類的時候,ST就會檢查並異步加載Ext.MessageBox。
Ext.MessageBox也可能依賴於其他類,這些類也將在後臺自動加載。Ext.MessageBox和動物類都加載完畢後,就會定義人類。然後就可以使用Ext.create實例化"人"了。
在開發過程中,多文件可以讓我們有效地管理代碼,但應用發佈後,應該儘量減少文件的數目以提高網絡響應速度。ST2的JSBuilder工具可以分析你的應用程序,並將你所有代碼連同你所用到的ST中的類合併成一個js文件。關於JSBuilder使用方法的介紹,請看指南的第二部分。
每種方法都有其自身的利弊,我們是否能夠取其精華,去其糟粕?答案是肯定的,在ST2裏,我們已經實現了這一目標。
命名約定
使用統一的風格來命名類、名空間和文件名有助於更好地組織代碼,保證代碼的條理性和可讀性。
1) 類
類名只能由字符和數字組成。不要在類名中出現數字,除非它屬於一個技術術語。不要使用下劃線,連字符,以及任何字母數字以外的字符。例如:
- MyCompany.useful_util.Debug_Toolbar 不要這樣寫
- MyCompany.util.Base64 這個OK
每個類都要有命名空間。用"."來爲類分配命名空間,把類分配到不同的包內。例如:
- MyCompany.data.CoolProxy
- MyCompany.Application
頂級的命名空間和類名使用駱駝拼寫法,其他的都用小寫。例如:
- MyCompany.form.action.AutoLoad
非框架本身的類,不要使用Ext作爲頂級命名空間。
首字母縮略詞也應該遵循上面列出的駱駝拼寫法約定。例如:
- 使用 Ext.data.JsonProxy 而不用 Ext.data.JSONProxy
- 使用 MyCompany.util.HtmlParser 而不用 MyCompary.parser.HTMLParser
- 使用 MyCompany.server.Http 而不用 MyCompany.server.HTTP
2) 源文件
類名直接映射到類文件的存儲路徑。因此,每個文件對應一個類(就像java一樣)例如:
- Ext.util.Observable 存儲位置爲 path/to/src/Ext/util/Observable.js
- Ext.form.action.Submit 存儲位置爲 path/to/src/Ext/form/action/Submit.js
- MyCompany.chart.axis.Numeric 存儲位置爲 path/to/src/MyCompany/chart/axis/Numeric.js
其中 path/to/src 是你存儲腳本的目錄(譯者注:這裏不是真的"path/to"而是你的app目錄),所有的類都應該保存在這個目錄下,並被正確地劃分命名空間。這樣Ext .require()方法才能正確地動態載入腳本文件。這樣對將來的維護和部署工作都也很會有幫助。
3) 變量和方法
- 跟類名一樣, 變量名和方法名只能由字符和數字組成。不要在類名中出現數字,除非它屬於一個技術術語。不要使用下劃線,連字符,以及任何字母數字以外的字符。
- 變量名和方法名應該使用首字母小寫的駱駝拼寫法。示例:
- 好的方法名: getHtml() getJsonResponse() parseXmlContent()
- 不好的方法名:getHTML() getJSONResponse() parseXMLContent()
- 好的變量名:isGoodName base64Encoder xmlReader httpServer
4) 屬性
- 除靜態屬性以外的類的屬性,其命名方式跟方法和變量的一樣。
- 靜態屬性全部用大寫命名,例如:
- Ext.MessageBox.YES = "Yes"
- Ext.MessageBox.NO = "No"
- MyCompany.alien.Math.PI = "4.13"