《Ext JS 4 First Look》翻譯之一:新特性


第一章 新特性                          
 
Extjs 4相對於之前的版本作出了重大的修正。其中包括全新的類系統、新平台的引入、API的修整和加強還有新組件的引入(如新的圖表和圖形組件)。Extjs 4提供更快速、更穩定的用戶體驗,並且讓開發人員更容易上手。
在本章我們將學習到下列內容:
    1.3.2 繼承
    1.4.2. 沙盒模式
    1.5.1. Data包
    1.6. 總結
 
 
1.1. 入手Extjs 4                                    
  Extjs是一個跨瀏覽器的富互聯網應用框架,其UI組件容易上手,並全球已有上百萬的開發人員正在使用。
  Extjs 2.x對 Extjs 1.x進行了重大的重構,其中包括重構組件模型構建方式,並伴隨着多個已有組件的重構。而Extjs 3.x是向后兼容Extjs 2.x。
  Extjs 3.x 及其之前的版本在應用程序展現上布局(layout)這一操作占據了絕大部分的時間。Extjs 4對此進行了重大的改進。而最終生成的HTML標簽也有所改進。
  對於Extjs 4.x Sencha團隊進行了多達4000個單元測試,測試覆蓋率達到90%,從而為大家提供一個更穩定可用的框架。
  而包含標准API在內的部分API進行了命名習慣的改進,同時使得部分的配置參數更易於使用。
 
1.1.1. 包和命名空間的改進
  對於Extjs 3.x 如PagingToolbar,Toolbar和Spacer均和其他類那樣屬於widgets包。這些類均可通過全局對象Ext來直接訪問,如Ext.PagingToolbar等。
  但在Extjs 4.x所有的類都按功能划分到相應的包和命名空間。如PagingToolbar、Toolbar、Spacer和其他與工具欄相關的類都已打包到toolbar包中,並且該包下面的類均以Ext.toolbar為命名空間。而其他類也作出了類似的改動,具體的類命名變化請參看原書的Appendix A,Ext JS 4 Versus Ext JS 3 Class Names。
 
  若您想繼續沿用Extjs 3.x的命名習慣那怎么辦呢?Extjs 4.x為每個類添加了alternateClassName屬性,該屬性表示該類的可選命名,也就是Extjs 3.x中的類名,如Ext.toolbar.PagingToolbar的alternateClassName屬性就是Ext.PagingToolbar。而在創建組件時采用Ext.create(className或者alternateClassName)即可。當然還是強力推薦使用Extjs 4.x的全新類名。
 
1.1.2. API文檔的使用(日后經常和它打交道)
  API文檔地址:http://docs.sencha.com/ext-js/4-0
  打開文檔首先看到的是歡迎頁。Home,API Documentation,Guides,Videos和Examples幾個標簽為於文檔的左上角。當我們點擊API Documentation標簽后,所有包的列表會在在左方和中間部分呈現。相關的類會以Base、View、Components、Data和Utilities來分類。當我們點擊某個類時效果如下:
  
  在頁面的上方,我們可以看到有一個圖標指示該類是一個單例類還是一個組件。如果是一個組件,那么就會顯示xtype屬性。(一定要分清哪個是類,哪個是組件哦,不然以后使用起來就麻煩許多了)
  在類名下面會根據具體類的情況顯示如下菜單項:Configs、Properties、Methods、Events、Super Classes和Sub Classes。接着還有一個搜索框,可通過它來查詢該類的特定屬性、配置項、方法等等。
  對於某些類的描述,API文檔中會列出一些實例,並且某些實例提供了即時預覽的功能,方便我們查看代碼執行效果。
  在頁面的右邊,會展現類的Alternate Names、Hierarchy和Mixns的信息。
  當大家打開API文檔時會發現有些方法被標記為deprecate,就是說這些方法已被棄用了。
  在API文檔的右上角我們可以看到一個搜索框,通過它可以在整份文檔中搜索特定的類、方法、配置項、屬性、事件、組合。
  當然API文檔還提供了官方的guides文檔,讓大家更容易入手Ext。
 
1.2. Extjs新平台的架構                                    
EXT JS 4 SDK 目錄如下:
 
 一般我們涉及最多的是ext-all.js和ext.js這兩個文件。
ext-all.js: 包含整套已壓縮的Ext JS框架。使用時引入該文件到HTML文件,然后項目中只需包含該文件和resource文件夾即可。目錄結構如下:
     --extjs
          --ext-all.js
          --resources
ext.js: 只包含Ext JS已壓縮的基礎庫。使用時引入該文件到HTML文件,然后項目中把src也包含進來。目錄結構如下:
     --extjs
          --ext.js
          --src
          --resources
我們還看到有*-dev.js和*-debug.js、*-debug-w-comments.js文件。下面我們逐一了解。
*-dev.js:內含無壓縮代碼和用於debug的代碼,建議在開發和測試環境中使用;
*-debug.js:內含無壓縮代碼但不含用於debug的代碼,建議在測試環境中使用;
*-debug-w-comments.js:內含無壓縮代碼但不含用於debug的代碼,建議在測試環境中使用。
 
SDK的其他文件夾:
docs:含完整的API文檔;
examples:含組件的使用實例;
overview:含新特性的快速瀏覽資料;
pkgs:含Extjs的模塊;
resources:含CSS和圖片、主題等文件;
src:含Extjs的完整源碼;
welcome:含index.html所需的所有圖片文件;
builds:含Extjs的額外文件;
jsbuilder:含JSBuilder工具,用於項目構建。關於JSBuilder的詳細資訊,請瀏覽http://www.sencha.com/products/jsbuilder(譯者本人還沒使用過這工具,請指教)
在builders文件夾中有下面幾個文件:
ext-all-sandbox.js:沙盒模式的ext-all.js和ext-base.js;
ext-core.js:Extjs的核心庫;
ext-foundation.js:Extjs的基礎庫。
 
  最后要講解的是bootstrap.js文件,它會根據具體的運行環境決定引用ext-all.js還是ext.js文件。除了下列情況外,bootstrap.js均會引用ext-all.js文件。
     1.主機名(hostname)為localhost
     2.主機名(hostname)為IP(v4)地址
     3.協議名為file
 
1.3.  Extjs 4的類系統                                        
Extjs 4類系統中有如下激動人心的特性:
類定義和對象實例化方式;
組合;
自動化getter和setter;
動態加載類文件;
靜態成員。
 
1.3.1. 類定義與對象實例化
  Ext JS4引入Ext.define和Ext.create方法來定義類和實例化。在本章我們將學習如何定義類和實例化對象。
1.3.1.1. 類定義
  Extjs 3我們需要繼承Object來定義類,代碼如下:
MyApp.NewClass = Ext.extend(Object,{
     // 類成員定義
});
 
  而Extjs 4我們可以如下的定義類:
Ext.define("MyApp.NewClass",{
     // 類成員定義
});
  很明顯,Ext.extend已被Ext.define代替了。
 
1.3.2 繼承
  讓我們對比一下Extjs 3和Extjs 4自定義window時的代碼吧!
下面是Extjs3的代碼:
Ext.namespace("MyApp");
 
MyApp.MyWindow = Ext.extend(Ext.Window,{
     title: "Welcome!",
     initComponent: function(){
          Ext.apply(this, {
               items: [{
                    xtype: "textfield",
                    name: "tfName",
                    fieldLabel: "Enter your name"
               }]
          });
 
          MyApp.MyWindow.superclass.initComponent.apply(this, arguments);
     }
});
 
var win = new MyApp.MyWindow();
win.show();
可以看到我們必須使用Ext.namespace來注冊自定義的命名空間,否則拋出MyApp未定義的異常信息。與此同時,若Ext.Window沒有完成加載,那么也會拋出Ext.Window未定義的異常信息。而Extjs 4就省去了這個麻煩。下面是Extjs 4的代碼:
Ext。define("MyApp.MyWindow", {
     extend: "Ext.Window",
     title: "Welcome!",
     initComponent: function(){
          this.items = [{
               xtype: "textfield",
               name: "tfName",
               fieldLabel: "Enter your name"
          }];
 
          this.callParent(arguments);
     }
});
 
var win = Ext.create("MyApp.MyWindow");
win.show();
  Extjs 4中以字符串的形式定義類和引用父類,所以並不存在該類未定義的說法。Extjs 4的ClassManager會檢查Ext.Window是否已完成加載並已定義,若沒有則推遲MyApp.MyWindow的實例化並自動完成Ext.Window的加載。框架會為我們管理各類的加載順序,並且Ext.define會自動監測和創建省命名空間,省心多了。
  另外我們可以看到,Exjts 3中調用父類方法的語句為MyApp.MyWindow.superclass.initComponent.apply(this, arguments),而Extjs 4就簡約為this.callParent(arguments)。
  對於override的方法使用this.callParent(arguments)就好比如C#的override方法中使用Base.方法名(參數1.......)。用於把子類的參數傳遞到父類的方法中。除了initComponent外,常見的使用形式還有:
     Ext.define("Parent",{
          constructor: function(name){
               this.name = name;
          }
     });
     Ext.define("Child",{
          extend: "Parent",
          constructor: function(name, sex){
               this.sex = sex;
               this.callParent([name]);// 參數為數組
          }
     });
     var c = new Child("John Huang", "male");
     或者 var c = Ext.create("Child", "John Huang", "male"); // 建議使用該形式實例化對象
     console.log(c.name);
     console.log(c.sex);
 
建議使用Ext.create實例化對象,這樣可以利用Extjs 4類系統的特性。
Ext.define是Ext.ClassManager.create的別名,Ext.create是Ext.ClassManager.instantiate的別名。
 
1.3.3 組合屬性(mixins)
組合是Extjs4的新特性,可用於實現多繼承。該屬性會以同步方式加載類文件,並實例化該類(譯者推理其內部使用Ext.create方法)。其他原文不翻譯了,直接上實例吧!
基本用法:
Ext.define("MyClass.A", {
     showA: function(){
          console.log("A");
     }
});
Ext.define("MyClass.B", {
     showB: function(){
          console.log("B");
     }
});
Ext.define("MyClass.C", {
     mixins: {
          classA: "MyClass.A",
          classB: "MyClass.B"
     },
     showC: function(){
          console.log("C");
     }
});
var objC = Ext.create("MyClass.C");
objC.showA(); // 控制台結果:A
objC.showB(); // 控制台結果:B
objC.showC(); // 控制台結果:C
 
方法同名時
情況1——多個mixins類擁有同名函數:
Ext.define("MyClass.A", {
     show: function(){
          console.log("A");
     }
});
Ext.define("MyClass.B", {
     show: function(){
          console.log("B");
     }
});
Ext.define("MyClass.C", {
     mixins: {
          classA: "MyClass.A",
          classB: "MyClass.B"
     }
});
var objC = Ext.create("MyClass.C");
objC.show(); // 控制台結果:A
Ext.define("MyClass.C", {
     mixins: {
           classB: "MyClass.B",
           classA: "MyClass.A"
     }
});
那么
objC.show(); // 控制台結果:B
結論:mixins中后者的方法無法覆蓋前者的同名方法。
 
情況2——mixins類與當前類擁有同名函數:
Ext.define("MyClass.A", {
     show: function(){
          console.log("A");
     }
});
Ext.define("MyClass.C", {
     mixins: {
          classA: "MyClass.A"
     },
     show: function(){
          console.log("C");
     }
});
var objC = Ext.create("MyClass.C");
objC.show(); // 控制台結果:C
結論:方法的調用遵循最近優先原則,就是先查詢直接類是否有該方法,有則調用,無則查詢mixins中包含的類。
 
情況3——mixins類與父類擁有同名函數:
Ext.define("MyClass.A", {
     show: function(){
          console.log("A");
     }
});
Ext.define("MyClass.B", {
     show: function(){
          console.log("B");
     }
});
 
Ext.define("MyClass.C", {
     extend: "MyClass.B"
     mixins: {
          classA: "MyClass.A"
     }
});
var objC = Ext.create("MyClass.C");
objC.show(); // 控制台結果:B
結論:方法的調用遵循最近優先原則,優先級順序從高到低——當前類、父類、mixins類。
 
當前類引用mixins類成員
Ext.define("MyClass.A", {
     show: function(){
          console.log("A");
     }
});
Ext.define("MyClass.C", {
     mixins: {
          classA: "MyClass.A"
     },
     alert: function(){
          this.mixins.classA.show();
     }
});
var objC = Ext.create("MyClass.C");
objC.alert(); // 控制台結果:A
 
1.3.4. 配置項屬性(config,自動創建setters和getters)
先上代碼吧!
基本使用方式:
Ext.define("MyClass.A", {
     config: {
          name: "John Huang",
          sex: "male"
     },
     show: function(){
          console.log(this.config.name);
     }
});
var objA = Ext.create("MyClass.A");
objA.show(); // 控制台結果:John Huang
objA.setName("John");
objA.show(); // 控制台結果:John
console.log(objA.getName()); // 控制台結果:John
console.log(objA.name); // 控制台結果:John
 
config屬性會將為其屬性自動添加setter和getter函數。
若打算修改setter的行為,可以重寫“apply屬性名”方法,該方法將為setter的內部實現。具體代碼如下:
Ext.define("MyClass.A", {
     config: {
          name: "John Huang",
          sex: "male"
     },
     applyName: function(val){
          this.name = "dev: " + val;
     },
     show: function(){
          console.log(this.name);
     }
});
var a = Ext.create("MyClass.A");
a.setName("John");
console.show(); // 控制台結果:dev: John
 
原文中說除了自動生成getter和setter,還會自動生成resetter。但經過實際操作我並沒發現有此方法,那就需要我們自定義resetter了。在自定義前我們需要理解config屬性、當前類、getter和setter的關系和原理。
下面我們通過實例來理解吧
Ext.define("MyClass.A", {
     config: {
          name: "John Huang",
          sex: "male"
     },
     applyName: function(val){
          this.name = "dev: " + val;
     }
});
var a = Ext.create("MyClass.A");
1. console.log(a.config.name); //  控制台結果:John Huang
2. console.log(a.name); // 控制台結果:undefined
3. console.log(a.getName()); // 控制台結果:dev: John
4. console.log(a.name); // 控制台結果:dev: John
5. console.log(a.config.name); //  控制台結果:John Huang
 
語句3的結果是不是和我們預想的John Huang有所出入呢?不是說調用setName的時候才會調用applyName嗎,為啥調用getName的時候也會調用applyName呢?其實調用getName的時候不定會調用applyName方法,只有當語句2結果為undefined時才會有如此的效果,而且只有首次調用時會調用applyName方法。如果在語句3前執行了a.name = "John"或者a.setName("John"),那么就不調用applyName方法。
  分析:
          其實getName內部實現在首次調用和第N次調用時是不同的。
          首次調用getName方法時的內部實現步驟如下:
          1. 檢查對象是否有name屬性,有則執行步驟2,無則執行步驟3;
          2. 返回name屬性,並更新內部實現;
          3. 以config.name為參數執行applyName函數,因為applyName函數體為this.name = .....,就會添加name屬性到對象中,然后更新內部實現。(若applyName函數體無this.name=...的語句,那么getName的返回值將是undefined)
          第N次調用getName方法是的內部實現如下:
          function(){ return this[q]; },直接返回對象的屬性。
 
  結論: setter和getter是將config的成員屬性復制(注意:為淺復制)為當前類的成員屬性,然后對成員屬性進行后續操作。
  因此我們在重寫applyName時需要遵守下列原則。
      不要修改config的成員屬性值
  而在類內部成員函數中訪問config的成員屬性時建議如下操作:
Ext.define("MyClass.A", {
     config: {
          name: "John Huang",
          sex: "male"
     },
     showName: function(){
          var name = this.name || this.config.name;
          console.log(name);
     },
     updateName: function(val){
          this.name = val;
     }
});
現在大家應該對getter和setter、config、當前類的關系有所了解了。下面我們來自定義resetter吧!
Ext.define("MyClass.A", {
     config: {
          name: "John Huang"
     },
     /*
     ** @param configProperties{object/string/array} config的成員屬性名
     ** @return {void}
     */
     reset: function(configProperties){
          if ("string" === typeof configProperties){
               if (this.config.hasOwnProperty(configProperties)){
                    this[configProperties] = this.config[configProperties];
               }
          }
          else if ("object" === typeof configProperties && null !== configProperties){
               var properties = configProperties;
               if ("[object Object]" === Object.prototype.toString.call(configProperties)){
                    properties  = Object.getOwnPropertyNames(configProperties);
               }
               for (var i = properties.length - 1; i >= 0; --i){
                    var property = properties[i];
                    if (this.config.hasOwnProperty(property)){
                         this[property] = this.config[property];
                    }
               }
          }
     }
});
 
對象實例化時設置config成員值
     在constructor方法中使用this.initConfig(參數對象),代碼如下:
     Ext.define("A", {
          config: {
               name: "John Huang",
               sex: "male"
          },
          constructor: function(config){
               this.initConfig(config);
          }
     });
 
     var a = Ext.create("A", {
          name: "Extjs",
          sex: "I don't know"
     }); 或 new A({
          name: "Extjs",
          sex: "I don't know"
     });
 
 
1.3.5. 動態類加載
  作為Extjs 4的新特性,Extjs框架為動態類加載提供一個整合依賴關系的管理系統。
  但我們應該避免在產品中使用該特性,因為類文件的加載操作將嚴重影響用戶體驗。而在開發環境中使用該特性將有利於調試和項目文件結構的組織。
  因發現原文中並未詳細地描述動態類加載的相關內容,以下內容為結合原文及API文檔總結而成,若有紕漏請大家多多指點。
  動態加載分類:
  1. 同步加載:加載類文件時javascript線程將被阻塞直至類文件加載完成或當前類定義的操作被阻塞直至類文件加載完成。

    1. 涉及的類、方法和屬性:
        1. Ext.create(加載類文件並實例化對象)
        2. Ext.Loader.syncRequire(別名:Ext.syncRequire) (加載類文件)
        3. Ext.Class.requires(加載類文件)
        4. Ext.Class.mixins(加載類文件並實例化對象)              
        5. Ext.Class.extend(加載類文件並實例化對象)
        6. Ext.data.Field.type(加載類文件)
        7. Ext.data.Association.associatedModel(或Ext.data.Association.model) (加載類文件)
        8. Ext.data.Store.model(加載類文件)
        9. 說明:上述1、2的是調用該語句時就會發起xhq請求加載類文件,且javascript線程將被阻塞;3、4、5、6、7、8的是在類文件加載完成后解析代碼時發起xhq請求,只阻塞該類的定義操作,而不會阻塞javascript線程執行類定義以后的代碼,若在實例化期間使用而事先未加載該類文件則會報異常(Ext.data.Store.model就是可以在實例化Store對象時設定其model值,若此時model指向的類文件沒有加載那么就會拋出異常)
          。例子:
      1.  Ext.define("Test", {extend: "B"}); var test = new Test(); 會報Test未定義的異常。
    2. 異步加載:加載類文件時javascript線程可繼續執行其他代碼(包括類定義的操作),當類文件加載完成后可觸發回調事件。
      1. 涉及的類、方法和屬性:
        1. Ext.Loader.require(別名:Ext.require)(加載類文件)
        2. Ext.Class.uses(加載類文件)
        3. 說明:上述1的是調用該語句時就會發起xhq請求加載類文件;2的是在類文件加載完成后解析代碼時發起xhq請求。
  啟動動態加載功能:
     Ext.Loader.setConfig({ enabled:true }); API文檔表示默認為false,但實踐證明默認為true。
  死鎖問題:
     動態加載類文件時,若多個類文件間彼此使用同步方式動態加載對方並形成類文件加載的閉環,便會產生死鎖問題,並使瀏覽器無法正常工作。實例如下:
     Ext.define("A", {
          extend: "B"
     });
     Ext.define("B", {
          mixins: {
               c: "C"
          }
     });
     Ext.define("C", {
          requires: ["A"]
     });
 
     Ext.syncRequire("A"); 或 Ext.create("A"); // 發起類文件加載請求
     說明:上述定義A、B、C三個類,並且分別使用extend、mixins、requires三種Ext.Class的屬性來設置相互依賴關系從而形成類文件加載的閉環。
 
     消除死鎖:
          1. 對於該類實例化時非前提條件的類文件,使用Ext.Class.uses屬性異步加載;
          2. 使用Ext.require方法發起異步類文件加載請求。(不建議使用該方法,因為應在類的設計階段就決定哪些依賴類需要用requires哪些可以用uses來加載)
 
1.3.6. 類的靜態成員屬性(statics)
     可通過Ext.Class.statics屬性來設置類的靜態成員,具體使用如下:
     Ext.define("A", {
          statics: {
               count: 0,
               appName: "A"
          },
          constructor: function(){
               ++this.self.count; 或 ++this.statics().count;
          },
          getCount: function(){
               return this.statics().count;
          },
          getAppName: function(){
               return this.self.appName;
          }
     });
     
     var a = Ext.create("A");
     a.getCount(); // 結果:1
     a.getAppName(); // 結果:"A"
     A.count; // 結果:1
     A.appName; // 結果:"A"
     說明:
          類定義內部不能使用"this.statics.成員名"的方式訪問靜態成員,而要使用"this.self.靜態成員名"或"this.statics().靜態成員名";
          類定義外部使用"類名.靜態成員名"來訪問類靜態成員。
          譯者理解:this.self獲取的就是類本定義本身,因此"this.self.靜態成員名"實際與"類名.靜態成員名"是一樣的。而"this.statics().靜態成員名"是另一種方法訪問類靜態成員。
 
1.4. 從Extjs3遷移到Extjs4                                  
  Extjs4在框架、核心庫和組件上都進行了重構。通過上面的學習我想大家對新的類系統已經有了較全面的了解了。現在我們一同來學習Extjs4的組件吧。當然有些變化並不兼容Extjs3,因此下面的內容會介紹如何從Extjs3遷移到Extjs4。
  1.4.1. 適配器(Adapters)
     在Extjs4之前的版本中,若我們打算使用除Extjs外如JQuery等工具庫時,我們需要引入由Ext提供的適配器文件,如ext-jquery.adapter.js。
引入的文件如下:
     ext-all.js
     ext-jquery.adapter.js
     jquery.js
ext適配器、第三方工具庫關系圖:
而在Extjs4中就省心多了,無需適配器的支持直接就可以引用如JQuery的工具庫。
引入的文件如下:
      ext-all.js
      jquery.js
關系圖如下:
 
  1.4.2. 沙盒模式
     作用:在同一個頁面中,同時使用Extjs4和其他版本的Extjs。
     相關文件:
                    ext-all-sandbox.js
                    ext-all-sandbox-debug.js
                    ext-all-sandbox-dev.js
                    ext-sandbox.css
     使用注意點:使用Ext4代替Ext關鍵字
                         引入的文件如下:
                              extjs3的文件
                              ext-sandbox.css
                              ext-all-sandbox.js
 
1.5. Sencha平台                                        
     Extjs一直提供基於自身的面向組件的類系統和架構,和相應配套的layout、state、utilities和data包。Extjs 4的架構與Extjs 3相似。
     
     Sencha誕生於2010年,與此同時還推出了Extjs的兄弟產品Sencha Touch。Sencha Touch是移動設備的javascript框架,其架構不同於Extjs3。到了Exjts4 release版時,Sencha決定融合Extjs4和Touch的架構,而Sencha平台就因此而誕生了。平台中提供部分通用代碼如data、layouts、大部分utility的方法和新的charting和animation包。通過這樣,Sencha的團隊就能持續提供穩定可用容易維護的產品代碼了。當然這樣就降低作為使用者的我們學習Touch的曲線了。(要知道Extjs的因功能強大,學習曲線可陡着呢)
 
1.5.1. Data包
  該包包括負責數據加載和保存的類。現在讓我們了解一下它吧。
  1. Store(數據倉庫):過去我們需要事先確認加載的數據是JSON還是XML格式從而選擇使用JsonStore還是XmlStore,現在Extjs4的最新Store類會自動監測加載的數據格式,並且Store還提供了排序、過濾的功能,通過最新的Reader類還能從服務端讀取格式化數據。
  2. Model(數據模型):Model是Extjs獨有的類,類似於Extjs舊有版本的Record,但又提供了如關聯關系(associations)和數據驗證(validations)的功能。
  3. Proxy(數據代理):Proxy類負責加載和保存數據,和接收Reader和Writer類的實例對象。我們可以將某類型的proxy附加到Store或Model類中(不像Extjs舊有版本那樣Proxy必須附加到Store中)。Extjs4還新增了LocalStorageProxy和SessionStorageProxy,提供將數據保存到HTML5 local storage和session storage的功能。
  提醒:上述的內容不是100%兼容Extjs舊有版本的代碼。
 
1.5.2. 圖表(chart)、圖像(draw)包
     Extjs4引入全新的Draw包,提供基於HTML5標准的自定義畫圖功能。我們可以畫如方形、圓形或者是文本等基本形狀。同時它也提供了通過SVG Path畫復雜形狀的功能。Draw包是Chart包的基礎。
     Extjs3引入全新的Chart組件,但其依賴於Flash。而Extjs4的Chart組件不再依賴Flash了,而是純javascript驅動基於SVG(Scalable Vector Graphics)、Canvas和VML(Vector Markup Language)。
     通過Extjs4我們可以畫任何想要的圖表。基本的圖表有Bar/Column、Line/Area、Scatter、Radar,我們可以通過這些基本的圖表來組合出各種自定義的圖表。
 
1.5.3. 布局(Layouts)
     布局是Extjs中最重要和強大的特性之一。Ext2中的布局渲染速度快但不夠靈活,Ext3中靈活性上進行了修改但犧牲了新能。而Ext4中重寫了布局引擎,現在不僅更靈活了而且渲染速度也更快了。此外還新增了如DockLayout、ToolbarLayout和FieldLayout等布局。
 
1.5.4. 表格(Grids)
     表格是我們用得最多的一個Extjs組件。Extjs4對其進行了重寫,使其更快、更容易自定義並擁有更高的性能。
     在Extjs3使用表格一次展現上千條數據時會出現各種性能問題,解決方法是使用一個插件來是表格支持緩存。而Extjs4的表格就內置緩存機制,現在不用再擔心該問題了。
     表格的編輯功能在Extjs4中也得到了改進。在Extj3中如果我們想使用表格來編輯信息,那么就要用一個特殊的表格——EditorGrid,或者是使用第三方插件RowEditor。在Extjs4中,內置了RowEditor插件,我們只需將該插件附加到表格(Grid)中即可編輯表格數據信息。(譯者語:將第三方官方化是使產品更穩定的做法)
     在Extjs3中若我們想為表格添加新功能,我們必須繼承表格后自定義表格類或通過自定義插件的形式來實現。Extjs4引入了Ext.grid.Feature,其提供了基本的特性讓我們自定義新的表格特性,而不必修改表格的核心部分,從而是表格更穩定。(譯者語:本人還沒搞懂該方式和plugin的區別,只是大概明白這樣做的理由是把可擴展的部分獨立出來,免除核心部分被修改而表格功能又能最大化的靈活修改)
     Extjs舊有版本中會完整地創建表格的HTML標簽,不管實際上是否使用了其某功能(編輯、行擴展),這使得產生了不少無用HTML標簽也降低了性能(譯者語:曾試過在IE6個上一次加載8000個HTML標簽,足足加載了2分鍾啊)。Extjs4遵循節約原則,開啟的功能才會為其創建HTML標簽,因此我們再也找不到Extjs3中的ListView組件了(ListView是Grid的輕量級組件,只用於數據展現)。
 
1.5.5. 表單(Forms)
     表單是另一個我們經常使用到的組件,而Extjs4為其增添了很多新特性。首先是不再限制表單只能用FormLayout作為其布局,而是可以使用任何Extjs提供的布局方式。
     另外Extjs4還提供了FieldContainer類,用於把其他組件(如表格等)打包到到表單中。
     關於數據合法性驗證方面也作出了重大的修整。
 
1.5.6. 可訪問性(Accessibility)
     通過javascript生產訪問性良好的應用是一件十分困難的事情。而Extjs4引入了下列三種特性來幫助我們提供應用的可訪問性。
     1. 每個組件均有特性來支持ARIA(Accessible Rich Internet Application);
     2. 支持鍵盤導航;
     3. 提供全新的主題來提供訪問性。
 
1.5.7. 主題(Theming)
     大家都知道修改Extjs舊有版本的主題是一件多么痛苦的事情,而Extjs4通過使用Sass和Compass這兩種優秀的工具使得自定義主題變得一件寫意的事情。
 
1.6. 總結                                            
     在這一章我們對Extjs4新的類系統有了相當程度的理解,對Extjs4相對於舊有版本的修整也有了大概的了解。我想大家應該和我一樣對這些新特性感到興奮,當然腦海中對Extjs4也產生了很多的問號。那下一章我們將一起繼續Extjs4的旅途^_^!

 轉載請標明出處哦!http://www.cnblogs.com/fsjohnhuang/archive/2013/01/29/2880705.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM