Ext 4概述

Ext 4概述

Ext 4有志誠成爲Web程序其革命性的開發平臺。框架中的每一個首要的組件幾乎都作了改善,而且屬於相當大幅度的改善。對於Ext3來說——4.0許多組件以及子系統都是表現得煥然一新!本指南會向您提供有關Ext3到Ext4期間變化所呈現的一方面。

如果您在閱讀本文檔時正好發現任何問題,請積極反饋,或來到Sencha論壇《遷移Ext3到Ext 4》的帖子還有來到Ext中文網之JS堂社區反饋吧!

一般性問題

該文檔通用於[#ext-core Ext Core]及[#extjs Ext JS]。

Ext 3的兼容性

我們幾次更新Ext JS累積下來,感覺當然就是第四版的變化幅度最大。第四版帶來了許多內容,這些內容並不兼容於Ext3。然而,我們盡力可以做到跟更前個版本最大化的兼容。

JS兼容化文件

加載Ext4完畢後,你可選擇加載這份兼容化文件。該文件的目的在於提供兼容Ext3的簡寫方式和覆蓋新參數爲適合舊版的參數。

注意: 此時此刻兼容化文件尚未釋出可用,不過應該會在發佈4.0正式版之前提供給大家。

沙箱模式

Ext 4完全基於沙箱設計的,因此可以讓舊版的Ext與Ext4”同處一室“,在同一個瀏覽器運行時中做到兼容(譯註:有一個桌面的例子,仍使用Ext3代碼)。從JavaScript角度看,原來所有修改對象原型的方法已被轉移,轉移到全局對象Ext之下。現在只需要建立一個Ext對象的引用,分配不同的名稱,就可以從以前舊版本的Ext中區分開來……

在標籤markup/CSS方面,由於Ext4採用了Compass和SASS框架並通過模板生成CSS,所以很容易設定一個前綴,供CSS規則之用,比如Ext.baseCSSPrefix屬性就是對應的前綴。結果,要與舊版Ext的CSS區分開來,也不是什麼難事了。

包與命名空間的更新

在重構過程中,全體類和包的結構已經發生了變化。如何變化將是根據嚴格的命名轉換來規範的,這一點對於重構的結果非常重要,以便於我們能更輕鬆地查找某一個類。例如Ext3的Button類、CycleButton類和SplitButto類就連同其他類歸類在/widgets中。儘管不同層次的對象卻也直接地命名在全局對象Ext身上。

在Ext 4,每一個類根據其特性的相似來決定其包的位置。雖然只是命名上的變化,但比起Ext3能更精確地描述對象。同樣拿Button按鈕爲例子,Ext4的類這樣分配:

  • 單獨設一個包src/button/
  • 代碼劃分出一個新的命名空間
  • 改名,如Ext.SplitButton→ Ext.button.Split

爲了儘可能地照顧Ext3的舊命名方式,Ext4的類有一個特殊屬性稱作“alternateClassName”,通過這個屬性就可以讓Ext3遺留項目採用Ext4新的類庫。例如alternateClassName: 'Ext.SplitButton'。當然,我們很希望你完全採用Ext4開發方式。

Ext Core

新型類系統

Ext JS 4 的類機制主要圍繞傳統OO模型而設計,彌補了Prototype OO不足。雖然性質上仍爲模擬的手段,但包含了比較完整的OO特徵,並且保持對舊Ext3類機100%兼容。Ext JS 4(連同 Ext Core)提供的新功能有:

  • 繼承方面Ext.defined代替了原來Ext.extend的寫法。
  • 自動計算依賴關係及動態類加載。
  • 多態
  • 靜態成員
  • 爲配置項自動生成的getter/setter方法

ext4-class-system.jpg

如何寫類?

你仍可在Ext4使用new ClassName()的語法,不過推薦使用Ext.define()函數定義新類。利用Ext類系統顯式定義好的類,將有什麼不同呢?關鍵字new仍然可用,可沒太大的特別。Ext.define還有一個好處,自動創所須的建命名空間,從而免去聲明命名空間的一步。

這裏是利用新語法定義的一個新Ext.Component子類。

// Ext 3:
Ext.ns('MyApp'); // 命名空間在Ext 3是必須的
MyApp.CustomerPanel = Ext.extend(Ext.Panel, {
    // etc.
});
 
// Ext 4
Ext.define('MyApp.CustomerPanel', {
    extend: 'Ext.panel.Panel',
    // etc.
});

加載類

Ext 4終於引入了動態類加載的系統了,雖然你可以選擇使用,也可以選擇忽略,但無論怎麼說,終於考慮這點,希望社區不再利用此缺點來指責Ext之龐大。首先交待一下提供哪些功能:

  • 動態加載(Dynamic loading):運行時期間,Ext內部會根據依賴樹的關係異步地下載類文件。這意味你不用再頁面上手動引入include子類的HTML標籤就可以加載你所需的資源,同樣不會造成阻塞。開發期間,動態加載的靈活性遠比關心頁面加載速度的意義打得多。
  • 動態生成build文件(Dynamic build generation):對於產品化,很希望就是打包爲一份文件,亦即build files。由於Ext已經清楚掌握依賴關係,所以很容易導出一個依賴關係圖,適合於某些自定義build配置。更開放的是,不限於Ext的命名空間,只要按照Ext類規範寫類,Ext就會計算它們的關係。在不久的將來,Ext開發者會享用”一鍵化“的build服務,而且一切都是經過智能計算的,決沒有冗餘的代碼。

動態加載必須有兩個前提條件,一是打開Ext.define;二是在寫類的時候須清楚指明依賴關係,當中關係所涉及兩個屬性說明如下:

  • requires: 所依賴的類。保證當前被實例化之前其他類就緒。
  • uses: 可選的依賴,不一定必須的(上面requires是指定必須的模塊)。uses的類可以異步下載,不限於一定要在類實例化之前(因爲異步的,可能之後)。

多態Mixins

多態(或譯作“混元”)可以爲現有的某個對象注入客制功能提供一種靈活的方式。mixins配置項,包括實例化類期間,允許給類原型“混入”新的能力。這與Ext.override函數作用類似。儘管該方法不會覆蓋現有的方法,就像override那樣不會直接覆蓋,但是該方法的參數還是。Mixins語法如下:

Ext.define('Sample.Musician', {
    extend: 'Sample.Person',
    mixins: {
        guitar: 'Sample.ability.CanPlayGuitar',
        compose: 'Sample.ability.CanComposeSongs',
        sing: 'Sample.ability.CanSing'
    }
});

靜態成員(Statics)

通過statics這個屬性可以設置類的靜態成員。

配置項 Config

Ext之中我們用術語“配置項(config items)”來表示任意的屬性,這些屬性在類原型(class prototype)都可以明確找到。有了配置項可以通過代碼的調用對API讀或者寫。Ext 4在這點上基本沒有什麼問題,唯一作出新內容的便是帶來了特定項“config”。當類定義中加入config屬性,其對象所包含的內容指的就是“配置項”,而且強調一點就是,圍繞配置項自動產生getter、setter、reset和apply方法,其中setter還提供模板方法自定義setter邏輯。基本示例代碼如下:

Ext.define('MyClass', {
    config: {
        title: 'Default Title'
    }
});

……根據以上介紹的機制,自動生成下列方法:

title: 'Default Title',
 
getTitle: function() {
    return this.title;
},
 
resetTitle: function() {
    this.setTitle('Default Title');
},
 
setTitle: function(newTitle) {
   this.title = this.applyTitle(newTitle) || newTitle;
},
 
applyTitle: function(newTitle) {
    // 自定義代碼
    // 如Ext.get('titleEl').update(newTitle);
}

Env命名空間

提供瀏覽器和操作的相關信息,還有告訴我們現代瀏覽器提供了什麼功能。

Ext.env.Browser

該類提供了全部瀏覽器的元信息(名稱、引擎、版本、是否Strict模式等等) ,用於全局對象Ext。

Ext.env.FeatureDetector

這是一個在Ext3中沒有類,完全新的功能,其功能在於檢測瀏覽器特性如何,主要針對現代HTML5和CSS3的特性,包括移動平臺在內的特性列表,有:

  • CSS 變形、動畫、轉換
  • Canvas、SVG、VML
  • 觸控能力、方向
  • 導航 Geolocation
  • SqlDatabase
  • Websockets
  • History
  • Audio
  • Video

Ext.env.OS

提供當前主機操作系統的信息(包括移動OS的列表)。

語言包(Lang Package)

同樣的功能在Ext中都會有,但這是一個新的包,之所以定義爲一個新的包,是爲了儘量不會影響到JavaScript的對象原型。儘管在對象原型中設置方法會比較方便,但是如果引入了其他JavaScript一起,很難說會不會構成衝突或者影響的說。再者,如果日後ECMAScript規範作出了修訂,會不會與Ext所定義的構成重疊呢?所以,要解決以上顧慮,我們還是把語言方法的命名空間定義在Ext對象之下,避免在對象原型身上定義的成員。

實際上雖然沒有分配一個“lang”的這麼一個命名空間,但是還是在源碼樹(Source Tree)中劃分了一份文件專門定義語言增強函數。前後變化如下:

  • Array → Ext.Array
  • Date → Ext.Date
  • Function → Ext.Function
  • Number → Ext.Number
  • Object → Ext.Object
  • String → Ext.String

請注意在兼容化文件中,仍會對核心對象的原型掛載方法之引用。重申一下,要真正升級到Ext 4並擺脫Ext 3舊的調用方式,就必須移除兼容化文件,最後升級到新的命名空間形式。

Ext.Function

Ext 4的函數原型Function prototype改變後,怎麼調用?最主要的一點就是命名上發生變化,如Function.createDelegate()和Function.createCallback()分別重命名爲 Ext.Function.bind()和Ext.Function();Function.defer()變化爲Ext.Function.defer()。由於使用頻率較高,我們在Ext對象上添加了快捷訪問方式,便是Ext.bind、Ext.pass和Ext.defer;其餘的函數方法像createSequence()和createInterceptor()就取消了,但引入新方法createBuffered()和createThrottled(),可以看看有什麼用途。

如下是一些語法糖說明前後之變化:

// Ext 3:
myFunction.createDelegate(this, [arg1, arg2]);
myFunction.defer(1000, this);
 
// Ext 4:
Ext.bind(myFunction, this, [arg1, arg2];
Ext.defer(myFunction, 1000, this);

Ext JS

通用問題

適配器(Adapters)

之前的各個Ext版本中都可以透過使用適配器(adpaters)的方式轉換第三方的JavaScript庫爲我所用。Ext4的話就沒這支歌仔唱了。改朝換代後,Ext JS應用程序的底層庫唯一限定爲Ext Core。不過我們依然可以繼續讓Ext Core與別的JS庫共存於一個JS運行時(實際上這就是爲什麼一些JavaScript對象其原型的方法都被<a href="#lang">移至到Ext中</a>去的原因)。不同的就是Ext不依賴於其他JS的底層庫了。

ARIA

爲達到ARIA用戶友好性的支持,而且是全面的支持,Ext對每一塊組件都細心打造進而在這方面加強之。Ext.Component新設有ariaRole角色的配置項屬性,默認是“presentation”(該角色僅表示爲可見的並沒有更高的含義,也沒有用戶交互的功能)。然後就讓後面更高層次邏輯來覆蓋它。例如,Ext.button.Button對ariaRole覆蓋,標識爲“button”,就表示這個是一個執行按鈕語義的這麼一個物件,這對屏幕閱讀者(Screen Readers)非常有用。不論按鈕外觀上表現得如何,API在實際會在渲染按鈕的過程中,對其標籤中添加上一項HTML屬性:role。總之,伴隨着ARIA的增強,Ext於用戶友好性(Accessibility)方面的提升大家應該是有目共睹的。

另一項ARIA重要的特性便是Ext.Component內建了aria-disabled支持。這一切都是自動進行的。當HTML標準屬性aria-disabled激活的話,就會爲屏幕閱讀者(Screen readers)表示出某些功能化UI元素的激活狀態。

Data

3.x的數據已經變化了不少,4.x繼續重構並加入更多新的元素。但其中一點必須提到的,便是4.x的數據被設計成爲能夠與SenchaTouch共享的代碼,也就說不論ExtJS或SenchaTouch使用同一套類庫。有關這麼方面的教程已經有不少了,這裏我們就一些必要的背景內容和新特性作一番介紹。當然,如果尚未了解的讀者還是建議你們閱讀一下之前的教程或資訊:

概述

針對Ext 3的兼容化文件使得數據包得以連續可供Ext3使用。論變化最大者,有Store和Proxy和新引入的Model。Model實質便是Record的升級。

  • Store與數據格式無關,即不再存在JsonStore/XmlStore之分。其加載和保存數據都經過Proxy來執行,而Proxy的數據由來自於Reader或Writer是裏。Store可執行客戶端的多排序、動態過濾和動態分組,並與服務端同步亦可。
  • Proxy既可附加到Store也可直接附加到Model,附加到Model的好處就是省去了處理Store的步驟。可以在配置Readers和Writers時候配置Proxy,從而來解碼或編碼來自服務器的數據。
  • Model 也舊版的Record和相似,加入了關係、驗證和更多的內涵

另外,Ext JS 4 也可以將Model持久化到本地存儲,利用全新的LocalStrorageProxy類就可以無縫地把數據保存的HTML5的本地存儲。

Draw

Draw包是全新的包沒有一點Ext舊的包袱。Draw包具備自定義的繪圖能力,通過抽象Canvas、SVG與VML引擎特性就可以根據當前瀏覽器的運行時選擇最佳的繪圖方式。Ext 4的<a href="#charting">圖表</a>就是依賴於這個Draw包,不但如此,Draw包還可以拓展至其他類型的圖形繪製。主要特性如下:

  • 基於HTML5 標準
  • 渲染原語形狀文本、圖形、漸變
  • 操控顏色、矩陣轉換等等的類庫
  • Ext.draw.DrawComponent
    • 繼承自Ext.Component
    • 檢測特性調優引擎
    • 可自定義引擎調優順序
    • 可參與佈局
  • 通過Ext.draw.Sprite 內建塊管理
    • 抽象的繪製元素
    • 常規化引擎API語法之間的差異
    • 屬性
    • 事件支持(通過繼承Observable)
    • 變形(旋轉、轉換、縮放)
    • 經由Ext.fx實現了動畫
    • SpriteComposites

圖表與圖形化 Charting & Visualization

圖表Chart不是好端端地用Flash做的嗎?現在4.0卻對Flash大聲“say no”——迴歸網頁標準的處理手法,要用Canvas/SVG/VML來做代替了Flash,命名空間就是Ext.draw.*。隨着改進一些複雜的JS動畫也成爲可能。和Dojo一樣終於有了屬於自己的圖形類庫。雖然新圖表可以順利支持到IE6的瀏覽器,不過還是希望不要太冒進,能夠繼續使用3.x的Flash。圖表引擎會自動選擇適合當前瀏覽器的渲染引擎。無論採用哪一種的圖表底層引擎,全體圖表的函數都定義爲同一種的API。這對用戶開發至關重要。

working-with-charts.gif

Fx

Ext 3的Fx類提供了一組有用的元素特效效果(平滑、高亮、漸顯等)。Ext 4基本上依舊不變,而且在簡單的元素效果的基礎之上,還有突破的發展,例如通過Animator類,可協調負責頁面上同時運行的多段動畫。再例如,無論調整大小還是定位都可以使用Fx”Target“類選擇目標(全稱Ext.fx.target.*),這爲創建動態UI打開了許多新的方式方法。

Layout

ComponentLayout

ComponentLayout是一種新型的佈局方式,許多複雜的組件就採用這種佈局(與之對應的爲ContainerLayout,“ContainerLayout”——傳統基於容器佈局的新名字)來計算內置元素的大小尺寸,以響應resize的調用。Field字段組件的FieldLayout佈局,關於labell控件和input元素控件的大小尺寸和定位都是來自於ComponentLayout的邏輯。

FormLayout

Ext 4已經沒有這種FormLayout了。請參閱[#form-layout Layout]的Form部分內容以瞭解更多。

BorderLayout

Border layout在Ext4或者Ext3中都是毫無差別的(即完全兼容)。

Panel的頭部Header現在可垂直方向佈置了,也就是說摺疊一個垂直方向的頭部時可以選擇在東面或者西面來摺疊,旋轉九十度也沒有問題(乃益於Ext 4新的<a href="#draw">Draw包</a>)。Ext3中的頭部實質乃元素而已,而Ext4的卻特有一個已經成熟的Ext.panel.Header實例,並有若干的方法。你可以使用佈局的新方法getPlacerHolder獲取頭部對象。當然,作爲Container的子類,Panel自然擁有全體Container的方法。對於第一次顯示的是閉合狀態的佈局,則不會渲染頭部組件對象。

另一個細微的差別就是已經不再支持cmargins配置項了。如同展開的面板那樣,Header容器現在是相同的邊距(margins)。這使得創建佈局的時候,不管組件閉合的狀態還是展開的狀態,看上去都更一致。

從更加靈活的佈局和制定佈局這兩點角度出發,現在BorderLayuout內部可允許嵌套HBox和VBox方式的佈局來創建邊界管理(the bordered arrangement)。

Component

普通的組件,只有設置其floating:true的話便變爲一個“浮動”組件,浮動於文檔流(document flow)之上。變爲浮動之後,可對組件進一步配置,可否拖動、可否調節高寬等問題都可以配置。甚至可以作爲子項加入到別的容器中去,但就是隻是浮動在其上面,不參與佈局運算。

全體浮動組件均有一個由ZIndexManager提供的z軸索引z-index。ZIndexManager來自於Ext 3的Window Group。一般情況下,單例Ext.WindowsMgr管理器負責管理像Windows這類浮動的組件。調用窗體對象身上的show()方法會在對document中進行渲染並顯示。除此之外,調用窗體的toFront()或者toBack()方法都會涉及ZIndexManager。

參與容器渲染的浮動組件,雖然是浮動的,但必定位於容器內。渲染的時候就會先獲取ZIndexManager之引用,然後查找需要z-index管理的父級容器。一般而言,單例Ext.WindowMgr將會提供一切信息。不過如果浮動的組件是一個浮動容器的後代,如Window的話,那麼這個Window會創建一個其專用的ZIndexManager實例,然後其下轄的浮動組件則會相對於這個Window的Z-index來進行管理。

現在Ext中可謂提出了新的形式,通過z-index作爲憑據來管理浮動的容器,無論容器多複雜,都可以快速地控制,也避免了組件之間的衝突影響。例如一個例子,窗體中的combo下拉箱子就總是在那窗體上,不影響其他層。

Form

Layout

Ext 3時代我們FormPanel利用FormLayout來定位field標籤,input控件,錯誤提示等等任務。但一個重要的消息就是Ext 4的FormLayout取消掉了,取而代之的將是新成員FieldLayout(爲<a href="#component-layout">ComponentLayout</a>的一子類)。標準佈局則統一管理基礎服務而這個FieldLayout又專門爲字段標籤控件所服務,而樣的結果,只要是標準佈局,就可以變爲具有表單特性的佈局。總之就是希望靈活性方面來個大躍進。

儘管標準佈局就可以包含表單了,但是仍提供一個表單面板FormPanel,其容器的佈局默認是anchor。

FieldContainer

爲管理表單佈局,Ext引入了新的Ext.form.FieldContainer類。這不但是一個標準的Ext.Container類,而且還是在Ext.Container的基礎上加入標籤(label)控件和錯誤信息等的這些考慮要素。這些label和錯誤信息的配置方法則與Ext.form.Field的無異,都是同一套API。就像真實字段輸入控件自動拉伸佔據空白空間那樣,容器下子組件都會自適應尺寸。這樣,在表單中加入複雜的組件也可以美觀地分組,並且讓表單的字段控件對齊起來。

Field as Mixin

長久以來要爲非Field組件加入字段式的能力如佈局、數據驗證、值管理等等是一道難題。最簡單的方法就是直接繼承於Ext.form.Field從而獲取相應的能力。雖然簡單可行,但卻破壞了原組件的繼承鏈。究其原因,在於Ext或JavaScript只能提供“單根繼承方案”,無法直接實現多繼承。當然這屬於Ext3的困窘,於Ext4中這一切都將成爲過去,通過提供多態<a href="#class-mixins">mixins</a>的支持,能夠讓我們告別舊有隻是複製Fields對像到類原型(Class Prototype)的拙劣手段。

Field被設計爲多態類,可混入到其他主類上,結果就是可讓任意組件擁有Field API的全部能量。當然你也可以根據需求來修改Field的具體行爲,例如重寫getValue方法和setValue方法。

Validation

一個常見的場景便是對用戶輸入的數據馬上進行有效性的檢測。早在Ext 3就有表單驗證了,前提是打開FormPanel的monitorValid選項。但是打開改選項後,每秒鐘都對錶單進行驗證,所以顯得十分的慢。

Ext 4不能容忍這點不足,所以重新設計過新的事件流如下:

  • 輸入框控件隨時會偵聽來自瀏覽器的事件,就是爲檢測內容有什麼變化。用戶一輸入內容,即打字輸入、剪貼、複製、拖動文本到輸入框都會使得輸入框內容發送變化。我們封裝這些瀏覽器事件爲changeevent事件以檢測輸入框的變化(下面會有詳述這部分細節)。
  • 一旦改變值,每個字段就會立刻對其自身進行驗證。當字段的有效性從無效的有效性轉變爲有效的有效性之時,便會觸發validitychange事件,反之亦然。
  • 字段觸發validitychange事件後,又會導致表單範圍內的有效性檢測,BasicForm觸發其自身的validitychange事件。

新的事件流可以立刻向用戶反饋用戶的輸入情況,之所以迅速是因爲新事件的性能比過去輪詢(polling)的機制快得多。故所以,事件流的方式將是默認的方式(Ext 3卻不是,必須顯式啓用)。當然你也可以禁止事件流的方式。

然而存在某些特殊的情況,輪詢的價值似乎值得重新考慮。一些瀏覽器(例如Opera和一些老版本的Safari)處於edit mode的時候(通過鼠標右鍵剪貼或粘貼時)總是不能觸發檢測事件。要解決這類問題,你可以打開FormPanel的pollForChanges參數以允許通過輪詢檢測字段的變化。觸發器仍如上述事件流的一般。——不得不說輪詢的做法性能上不好,但比起Ext 3輪詢的強度則沒那麼嚴重,因爲每次輪詢只是對值的觀察,而沒有繁重的數據驗證的參加(指值解析、轉換和正則模式匹配等的驗證)。

當檢測到字段發生變化時,就會對字段內容進行數據驗證(假設已打開validateOnChange)。檢測內容變化的瀏覽器事件多種多樣,都保存在checkChangeEvents參數中,我們可以訪問該參數來獲取該事件名稱。根據瀏覽器的不同,可能出現的checkChangeEvents值有:

  • 對於InternetExlorper而言checkChangeEvents爲change和propertychange。
  • 對於其他瀏覽器而言checkChangeEvents爲change、input、textInput、keyup。

兩點所列出的大體上包含可以檢測到的用戶輸入變化的事件。幾乎可以支持到全體可支持瀏覽器,然而,還是有一些情形不能檢測變化,列出如下:

  • Safari 3.2或更老的版本:鼠標右鍵剪貼或粘貼,拖到文本到textareas。
  • Opera 10和11:拖到文本到輸入框和textareas,鼠標右鍵剪貼輸入框和textareas的內容。
  • Opera 9: 除了Opera 10 and 11提到的外,還有用鼠標右鍵粘貼輸入框和textareas的內容。

(譯註:Oprea的QA咋留着這麼多bug……:))如果你必須要通過輪詢才能檢測到值發生變化的話,你可以打開FormPanel的配置項pollForChages和配置項pollInterval,或者設置一計時器不停調用startPolling()方法和stopPolling()方法都可以檢測到。

Ext 3支持按鈕的formBind屬性,目的在於可以表單驗證對在表單元素範圍之外的按鈕控制其enabled/disabled狀態。Ext 4則不限定在表單驗證,而是拓展至FormPanel中任意的組件。

FieldDefaults

舊Ext 3的FormLayout包辦了全部字段的在表單怎麼顯示的問題,如hideLabels、labelAlign等等,都是FormPanel的配置項屬性。由於Ext的表單容器採用標準佈局,不存在FormLayout,要指定普通字段的佈局屬性的話,就要進入層層的容器或字段,將會十分複雜。故所以FormPanel特別提供一個fieldDefaults對象,指定的值供全體字段對象所使用,不論嵌套多少層的FormPanel。

BasicForm

Ext 3的BasicForm用途不是很廣,只是在FormPanel內部偶爾用一下。Ext4的話BasicForm重新打造得更爲靈活和易於擴展。新Basic不再需要一個容器以分配元素,也不需要其所在的容器手動通知BasicForm加入或刪除字段。也就是說,它完全與FormPanel解耦,有條件在任意容易中發揮管理表單字段的能力。

數據表格(Grid)

這次升級Ext 4全部重寫了Grid組件。顯然,諸多理由和原因迫使我們升級Grid,但Ext 4 Grid向後兼容方面真的很難顧全。爲此,我們將會提供一份關於Grid在Ext3升級到Ext4的指南。

智能化渲染

舊Ext JS 3 Grid工作起來還是蠻不錯的。但透過“最小公分母(least common denominator)”的方法論來確定其各種功能的話,很容易帶來一點不足的就是,伴隨着Grid的每一項功能,都會生成大量的HTML Markup產生。我們不得不面對這個問題。於是在ExtJS 4中,規定Grid的每一項功能,只會根據開發人員設定與否,纔會渲染出與之對應功能的Markup在頁面上。Grid默認啓動時只有爲數不多的Markup而已。這樣設計API的結果,便是在渲染頁面以及Grid整體效能這雙方面均得到極大的提升。

標準化佈局

渲染流水線得到了改善,Grid的其他方面亦齊頭邁進,不甘人後。許多Grid的部分都被規劃成爲單獨、清晰的Component組件,整合到標準的佈局管理系統中,並非舊版中直接處理內部Markup、CSS的那種方式。這使得API可以聯合框架的其他強大的特性,進而來統一Grid的渲染流程。而這些過程,仍維持在精確到象素級別水準(pixel-perfect)的UI體驗。

例如,新的HeaderContainer類就很能說明這個問題。Ext3中的列頭部(Column headers)整合到Grid的話感覺是比較生硬的,因此不太容易客製化。Ext4的列頭部作出改進,其所使用的HBox標準佈局就能夠讓你在每一列上輸入靈活的flex值。

擴展新功能

在Ext JS 3裏面爲Grid加入新功能,一般API接口方面有良好的考慮。但現在來看,卻沒有一種清晰的流程方法去指導,顯得比較亂。有時通過寫插件(Plugins),有時就寫子類。總之擴展Grid的話可能會比較複雜。要解決上述問題,實質就是提供一種徹底靈活的選項操作。ExtJS 4將引入全新的一個Grid基類,稱作Ext.grid.Feature。通過繼承這個Feature類,對任何Grid其所在模板(Template)進行修改,就可以控制當前Grid視圖生成的Markup結果。Features類跟舊版的GridView相似,但能力更強,也更爲有用。之所以有用和強大,是在於其對延續Grid功能這點上表現得更爲簡單和適配。Grid裏頭的一些功能如RowWrap、RowBody和Grouping都是Fetures之子類。

Ext 4 grid相關功能的演示例子有如下:

  • RowWrap
  • RowBody
  • Grouping
  • Chunking/Buffering

虛擬滾動

Ext 4 Grid已經可以做到原生支持“按需加載(load-on-demand)”的數據視圖了。雖然這是個虛擬視圖,但是的確可以能夠做到數據的緩衝。無論上百條抑或達上千筆的數據,都可以保證在Grid輕鬆顯示。無疑,這將大大擴充了Grid數據處理能力。

編輯單元格控件

我們依然拿舊版對比一下。Ext 3裏面要編輯Grid單元格,就必須制定EditorGrid類。通過繼承方式可能不太靈活,於是Ext 4就否決了繼承的方式,而是採用“插件化”的方式。通過Ext JS4的Editing插件可以自由綁定到任意的Grid的實例,對於全體任何類型的Grid均可使用。於是乎,此舉又爲提高“靈活性(flexibility)”添潑了一抹濃彩。此外,對於Ext 3中很受大家所歡迎的一款擴展:RowEditor,在這次發佈我們也將RowEditor正式加入的Ext 4包中去,成爲標準類庫的一員。

DataView

GridView的父類更改爲DataView。這樣做的好處不僅減少了代碼量,而且使得Grid更容易制定。因爲可以直接發揮DataView的選區模型,應用到任意一種的視圖,包括那些非連續的選區,例如通過鍵盤Home、End、PageDown和PageUp所產生的選區。

面板Panel

支持了邊界接觸(Docking)

Panel的改變之一便是通過面板特定的組件佈局類(a panel-specific ComponentLayout)來負責管理其邊界內所接觸的元素項。面板body元素會鋪張至任何空白的位置。任何組件都可以通過設置目標面板的dockedItems配置項屬性來相接觸,而且對方面板的dock屬性也要與之設置好才行。如此一來,Ext3中困難重重的水平界工具條現今已大幅改進其靈活性,在Ext4中輕而易舉地實現上述功能。

頭部Header的改進

頭部Header 現今爲容器子類的第一類公民,從而獲得子組件管理與佈局的特性。你可以設定headerPosition的配置爲 'top'、'right'、'bottom'或'left'的其中之一來決定和ader所依靠的位置(new docking support)。

Tool工具按鈕(即像關閉、最小化此類的按鈕)雖然在Ext3中都有,不過現在是屬於Component的子類了,顯得更靈活。

Resizer

Ext很早就有調節大小的控件,但只爲DOM元素服務。現在Ext 4任意組件也可以透過Ext.resizer.Resizer達成調節大小的一方面功能。這對浮動的組件比較有用,或者說沒在Ext容器體系以外渲染組件的時候,將會派上用場。

只要設置組件resizable:true的配置項,那麼將會分配多個調節手柄到組件的邊界上。默認用一個代理元素來產生調節大小的效果,mouse up之後就會真正讓組件的大小進行變化。具體的調節行爲可以通過修改配置項對象resizable,——這個對象便是Resizer類的參數對象。

ComponentDragger

Ext一向支持多種方式的拖放支持,不過尚在DOM元素的級別。Ext 4改進後,新引入的Ext.util.ComponentDragger提升到組件級別,使得組件的拖動更簡單。ComponentDragger對浮動組件比較有用,對非容器模型的UI控件也是有的。

只要設置組件的配置項draggable:true,這個組件就可以通過鼠標來拖動了。Windows本身就是可拖動的。拖動期間,被拖動的dragger實際是一個空白的“幽靈”,鼠標鬆開後,面板或窗體移動到目的地位置,然後這個“幽靈”也會消失。指定draggable的配置項可以修改dragger行爲,該配置對象同樣適用於ComponentDragger的配置對象。

分割欄 Splitter

箱子佈局HBox和VBox都可以包含Ext.resizer.Splitter組件,用於調整箱子之間的尺寸。最小和最大的尺寸都可以支持的。默認下,對箱子佈局其中一個flex項進行調整大小的話,就會把原來的flex的值變爲精確的像素值,flex值將會刪除。如果不想這種情況出現,可以配置maintainFlex:true就可以保持flex值,哪怕在調整大小操作之後。但這隻適用於分割欄劃分兩塊中的其中一塊。

 

TabPanel

與其他衆多Ext的組件一樣,組成一個TabPanel的主要部分,已被分解併成爲Ext4組件之第一公民。Tab本身在Ext3只是若干DOM元素,現在Ext4中卻是重新認識Tab爲一個”按鈕“,容納這些Tab的容器則就是一個容器。各方面顯示,4.x的TabPanel比起Ext3提升的靈活性是顯著的。

以上的做法,就是從包含內容的子麪包中分離出來這些tabs,形成不同的小組件。正因爲這樣的分離,我們現在可以允許了tab面板中顯示標題titile、工具按鈕等在舊Ext3中無法想象的功能特性。

工具條 Toolbar

Toolbar現在爲容器之第一公民了,加入新組件或自定義Toolbar佈局的話,比起Ext3來得更加容易。

主題(Theming)

承蒙厚愛,Ext之主題一向被認爲出彩的地方,看起來很好,可修改起來卻不容易。雖然Ext 3通過分離結構以及可視化樣式表改善了主題制定任務,但是尚不足夠,仍有冗餘、繁雜的瀏覽器私有特性以及一個關鍵,便是CSS本身語言不足所帶來的問題。

參考資源

Ext 4 Theming (video)

Ext 4 Theming (slides)

Compass與SASS

Ext的主題樣式藉助了新工具來實現的,內部透過轉換CompassSASS來作爲主要CSS輸出工具。SASS爲CSS標準的超級,加入了許多新的高級功能。

  • 內嵌選擇器
  • 變量
  • 多態
  • 選擇器的繼承
  • 編譯和壓縮
  • 哪些組件需要的樣式就導出,不需要的樣式就不導出

Markup的不同

Ext現在支持了特定版本或瀏覽器的組件markup,比起Ext3跨越了一大步。

文檔

  • 支持類更多的新元素(requires、mixins等)
  • 支持遺留項元素
  • 記錄瀏覽歷史
  • 內涵例子、視頻等
  • 關注話題
  • 多框架和版本的支持
  • 本地搜尋

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章