ExtJS 允許用戶使用Ext.define 自定義類。本文將通過實例介紹如何使用Ext.define自定義類,並介紹ExtJS 的動態加載(Require方法)的使用方法。
Javascript自定義類
在Javascript中,自定義類是這樣的:
var Person = function (name, age) { this.Name = ""; this.Age = 0; this.Say = function (msg) { alert(this.Name + " Says : " + msg); } this.init = function (name, age) { this.Name = name; this.Age = age; } this.init(name, age); }
在這段代碼中,我們定義了Person類,它具有Name 和 Age 兩個屬性,具有 Say 和 init 公有方法。當類創建的時候,會定義通過調用init方法實現類的初始化(所以init方法可以看作是類的構造函數)。我們看一下該類的用法:
var Tom = new Person("Tom", 26); Tom.Say("Hello");
運行效果如圖:
我們簡單的介紹了如何在原生的Javascript中自定義類,由於本文重點是介紹ExtJS 中自定義類的方法,所以更多關於Javascript 自定義對象的方法,您可以參考我之前的文章:《自定義Javascript類》,下面進入本文的正題,看看如何使用ExtJS.define 方法自定義類。
ExtJS 中自定義類
在ExtJS中,我們同樣定義一個Person類,首先看一下具體的代碼:
Ext.define("Person", { Name: '', Age: 0, Say: function (msg) { Ext.Msg.alert(this.Name + " Says:", msg); }, constructor: function (name, age) { this.Name = name; this.Age = age; } });
在這段代碼中,我們使用了Ext.define方法自定義一個Person類,它同樣具有Name 和 Age 屬性,具有Say 方法,constructor 則的它的構造函數,有了專用的構造函數,我們就省去了寫init方法的代碼,直接在構造函數中完成對類的初始化,它的使用方法沒有改變,仍然是之前的代碼:
var Tom = new Person("Tom", 26); Tom.Say("Hello");
看一下運行效果:
ExtJS 中類的繼承
ExtJS 允許對現有的類進行擴展,其擴展可以通過繼承來實現。接下來我們就對剛剛使用ExtJS定義的Person類進行繼承,定義一個Developer類,它繼承自Person,同時還擁有Coding方法,代碼如下:
Ext.define("Developer", { extend: 'Person', Coding: function (code) { Ext.Msg.alert(this.Name + " 正在編碼", code); }, constructor: function(){ this.callParent(arguments); } });
從代碼中可看出,ExtJS 使用 extend來實現繼承。我們為Developer 類添加了Coding 方法,這是我們對Person類進行的擴展。在構造函數中,通過調用this.callParent 方法,實現對屬性的初始化。需要說明的是,如果此處只調用了父類的構造方法,則可以省略掉,ExtJS 會自動為我們調用父類的構造函數。所以我們此處的代碼可以進行簡化:
Ext.define("Developer", { extend: 'Person', Coding: function (code) { Ext.Msg.alert(this.Name + " 正在編碼", code); } });
需要注意的是,如果你在子類中使用了構造函數,ExtJS 則不會再自動調用父類的構造函數。
我們要使用Developer類,代碼很簡單:
var Bill = new Developer("Bill", 26); Bill.Coding("int num1 = 0; ");
運行效果如圖:
ExtJS 中類的選項 - config
首先看一個例子,我們在ExtJS中定義一個Window對象,代碼如下:
var win = Ext.create("Ext.window.Window", { title: '示例窗口, width: 300, height: 200 }); win.show();
在上面的代碼中,我們通過Ext.create方法創建了一個Window 對象,Ext.create 方法的第一個參數是類名,第二個參數是類的選項,它是一個JSON格式的對象,用來初始化Window對象。我們的窗口運行如下:
試想一下,如果我們的類中有幾十個屬性,那么我們使用構造函數就要傳入幾十個參數來對它完成初始化,這是一件很恐怖的事情。還好ExtJS 為我們提供了這種便利,我們可以在定義類的時候為它添加配置項,然后調用ExtJS 內置的方法完成初始化,並可以生成訪問器(類似於C#里面的get和set方法)。
我們來修改Person類,使它可以通過config初始化:
Ext.define("Person", { config: { Name: '', Age: 0, }, Say: function (msg) { Ext.Msg.alert(this.Name + " Says:", msg); }, constructor: function (config) { this.initConfig(config); } });
我們在類的定義中添加了config項,將需要在配置中完成的屬性添加在里面,而在構造函數中,我們通過調用this.initConfig方法完成對config的初始化。看一下用法:
var Tom = Ext.create("Person", { Name: 'Tom', Age: 26 }); Tom.Say("Hello");
我們在定義Person類對象的時候,使用Ext.create方法,傳入類名Person以及配置項,然后調用Tom的Say方法,運行效果如圖:
除了代碼更加清晰簡潔以外,ExtJS 還為我們生成了訪問器,我們可以通過下面的方式訪問Tom的屬性:
Tom.setAge(20);
alert(Tom.getAge());
ExtJS 生成了get、set方法,我們可以通過這樣的方式來訪問對象的屬性。
ExtJS 中類的別名 - alias
在我們查看ExtJS API 的時候,在左側常會有這樣的說明:
紅色方框圈出的部分是這個類的別名,它對應類的全稱是 Ext.window.Window,由此可以看出別名更加簡單,容易記憶和書寫。我們在實例化類的時候,可以使用別名來替代類名全稱,例如我們之前定義的win對象,他的代碼可以修改為:
var win = Ext.create("Ext.Window", { title: '示例窗口', width: 300, height: 200 }); win.show();
看完例子,你是否也想在自定義類中實現別名呢?為了更好的演示別名,我們對Person類做一個簡單的修改,將類名的全稱修改為MyApp.Person(相當於為Person添加了命名空間):
Ext.define("MyApp.Person", { config: { Name: '', Age: 0, }, Say: function (msg) { Ext.Msg.alert(this.Name + " Says:", msg); }, constructor: function (config) { this.initConfig(config); } });
我們只修改了第一行,其它代碼不變。這個時候我們使用之前的代碼實例化Person類:
var Tom = Ext.create("Person", { Name: 'Tom', Age: 26 }); Tom.Say("Hello");
刷新頁面,很不幸的是我們得到了兩個錯誤:
第一個錯誤,ExtJS的動態加載檢測到系統當前沒有Person類的定義,於是就自動加載Person.js,這個路徑是不存在的,於是出現了404未找到錯誤。關於動態加載的問題我們接下來會講到。
第二個錯誤,Person 未被定義,所以系統拋出類型錯誤信息。要想解決這個問題,我們需要將Ext.create方法的第一個參數修改為 "MyApp.Person"。但我們在這里不這樣做,因為我們依然希望通過使用Person來完成,那么怎么辦呢?這時就用到別名了。
我們為MyApp.Person 類添加別名:
Ext.define("MyApp.Person", { config: { Name: '', Age: 0, }, alias:"Person", Say: function (msg) { Ext.Msg.alert(this.Name + " Says:", msg); }, constructor: function (config) { this.initConfig(config); } });
很簡單,只要一行代碼,ExtJS 為我們完成了別名的定義。
重新刷新頁面,我們得到了想要的結果:
ExtJS 中的動態加載
在Ext.create 方法的介紹中,有這樣一段描述:
它的意思是:如果Ext.loader 可用,且類還沒有被定義,它將試圖通過同步加載來加載類。
接下來我們來試試類動態加載的功能。我們的類MyApp.Person 類的位置是:
我們要告訴ExtJS,我們的MyApp命名空間的路徑,代碼如下:
window.rootUrl = "@Url.Content("~/")"; Ext.Loader.setConfig({ enabled: true, paths: { MyApp: rootUrl + "Resources/js/MyApp" } });
我們可以將這段代碼寫在Layout中,因為它在每個頁面中都要用到。
在完成Loader 的配置以后,我們就可以移除掉對Person.js的引用了,然后我們的程序依然能夠正確的運行:
var Tom = Ext.create("MyApp.Person", { Name: 'Tom', Age: 26 }); Tom.Say("Hello");
注意,我們這里使用的是類的全稱,因為使用別名的時候沒有辦法找到正確的路徑。加載器會通過類名類匹配路徑中的MyApp,然后加載Person.js。
另外,我們還可以手動的加載Person.js,代碼如下:
Ext.require("MyApp.Person");
當手動加載MyApp.Person 類以后,我們就可以繼續使用別名來定義類的對象了:
var Tom = Ext.create("Person", { Name: 'Tom', Age: 26 });
在本節中,我們介紹了在ExtJS 中自定義類的一些方法,以及動態加載的部分內容。自定義類還可以通過mixins 實現多繼承的關系(將別的類中的方法導入該類中),通過requires 實現依賴其它類的關系(在實例化的時候會自動加載依賴的類),通過將 singleton 指定為 true 類定義單例類(該類只能有一個實例),通過statics 定義靜態方法等。
在下面的章節中,我將介紹如何使用數據模型,請敬關注!