Table of contents


本文章內容在說明EXT JS 4的基本知識。”EXT JS 4”(以下簡稱ext)是Sencha公司出的一套javascript lib,有兩種授權模式,但基本上”就是要錢”。

從架構面來看ext可以分成兩部份,ext core跟ext UI componment,ext core的部份是跟ui比較沒有關係的核心模型,像資料模型Model、後端的溝通處理用的Proxy、以及PluginExtension 。而ext UI componment就是一堆UI元件。建議在看完簡單的文件,玩玩ext的hello word程式後,可以先從內功(ext core)下手,等內功任督二脈打通了後,外功(UI元件)再個個擊破就很快了。

Data Package

整個Data Package的主要觀念如下圖:

extjs_101_001.png

Model

Model就是資料模型,像User的model,就是具有username, password, email,….這些屬性(圖中的Field)的資料模型, 模型的驗証邏輯(圖中的Validation)及與其他模組關聯(Association)。

Validation

可以是單位欄位性質得欄位型態,內容,長度…驗証,也可以是同一個model裡欄位與欄位間關係的驗証,甚至少 Business Logic的驗証。

過於複雜的驗証,最後再後端處理後,再送回前端

Proxy

Proxy負看將資料載入model或儲存model的資料。可分為Client Proxy及Server Proxy

Client Proxy
  1. WebStorageProxy
    1. LocalStorageProxy
    2. SessionStorageProxy
  2. MemoryProxy
Server Proxy
  1. AjaxProxy - 透過AJAX跟後端溝通(常用)
    1. RestProxy - 透過REST跟後端REST service進行溝通(利用HTTP protocol 的uri代表資源位置,GET, POST, PUT, DELETE methods來對資源進行Read, Save, Update, Delete的動作)
  2. ScriptTagProxy - 透遛JSONP(JSON with Padding)的方式與其他domain的server溝通
  3. DirectProxy -

JSONP(JSON with Padding):browser的限制不能存取其他網域(domain)的資料,而JSONP是利用JSON

  • callback function來跨越這個限制
Reader

Reader負責來解析資料格式,目前有

  1. JsonReader (預設)
    1. ArrayReader
  2. XmlReader
Writer

Writer比Reader複雜一些,通常是被Server Proxy使用,Writer裡面有一個叫Operation,Operation會決定url的格式內容及參數。 透過改成Operation.action 為’create’, ‘read’, ‘update’ or ‘destroy’可以決定要對Server Proxy送出什麼樣的url

Store

如果將Model視為處理一筆資料的物件,那麼我們可以說,Store多筆資料(Model)的物件,Store跟Model一樣可以透過Proxy讀取或儲存資料。 而Store因為資料內容是多筆的,所以,還可以對這些資料進行排序(sorting),過濾(filtering),郡組(Grouping)或查詢(querying)的動作.

如何看懂API

為了學習如果使用API進行開發,以下設計了一個簡單的例子來說明如果使用FireBug

  • ExtJS的API說明文件來進行練習

一般來說,我們會透過ajax proxy跟後端要資料,一開始,我們可以用一個簡單的純文字檔,讓proxy直接跟檔案要資料,而不是跟server side要

    [{"id":1,"name":"kent","email":null},{"id":2,"name":"juiwen","email":null},{"id":3,"name":"Roger","email":null}]

    <html>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <head>
    <script type="text/javascript" src="%EXT_HOME%/ext-core-debug.js"></script>
    <script type="text/javascript" src="%EXT_HOME%/ext-all-debug.js"></script>
     
    Ext.require([
                 'Ext.data.*',
             ]);
    Ext.onReady(function(){
     
     
        Ext.regModel('User', {
            fields: ['id', 'name', 'email'],
            proxy: {
                type: 'ajax', // load using HTTP
                url: 'model.json' // 載入下面的json檔案
            }
        });
        var user = Ext.ModelMgr.getModel('User');
        // 宣告剛成後,user只是一個Ext.data.Model型別的物件
        // 查Ext.data.Model的API doc可以知道,有一個load method可以用來載入資料
        // 載入json file第一筆{id=1, name='kent'}記錄進user
        user.load(1, {
            scope: this,
            failure: function(record, operation) {
                // 載入失敗時,這個method會被呼叫
            },
            success: function(record, operation) {
                // 載入成功時,這個method會被呼叫
                conlog.log(record); // record本時為json file的第一筆資料,但是Ext.data.Model
            }
        });
        console.log(user); // 注意:這樣得到的user是會空的,因為,取得資料的method 'load'是非同步的,所以,load還沒取回資料前,就會執行load之後的動作了
     
     
        var userStore = new Ext.data.Store({
            model: 'User',
            autoLoad: true,
        });
     
        userStore.on('load', function(self, records, success) {
            // Ext.data.Store.data是Ext.util.MixedCollection型別,MixedCollection中有each method可以取得集合內的每一個內容,每一個內容均為Ext.data.Model
            userStore.data.each(function(item, index, length){
                // item此時為json file的"某"一筆資料,被包裝成Ext.data.Model型別,Ext.data.Model有一個data的屬性可以取得物件
                console.log(item.data.name)
            });
        });
    </script>
     
    <title>Model Example</title>
    </head>
    <body>
    EXT JS Model Test
    </body>
    </html>

透過plugin + API Doc

EXT是利用動態語言JavaScript寫的,由於動態語言的特性是在Runtime的才能知道物件真正的內容為何,如果要光靠API做物件型別的推斷,會很辛苦。 再加上EXT JS 4版後,採用Mixins的技術,會讓物件型別的推斷更加麻煩,所以,建議在API不熟前,可以多利用Debugger工具,在runtime去查出物件的真正型別 ,這樣對初學者,會比較容易克服ext的進入門檻。

API inspect in action

這裡利用FireBug + extjs plugin來觀查extjs元件內容並說明如何搭配API文件來將程式改成符合我們需求的設定。

FireBug必須利用script debugger的功能,設定中斷點後,執行script會停在中斷點上,便可在執行時可以得知物件型別,對照API一起看,就會很清楚了

extjs_101_002.png

Ext.Template

範本功能是透過建立一個固定的範本,然後可以將範本裡面特定的內容給取代掉。

var t = new Ext.Template("<div>Hello {0}.</div>");
t.append('some-element', ['foo']);

var t = new Ext.Template([
    '<div name="{id}">',
        '<span class="{cls}">{name:trim} {value:ellipsis(10)}</span>',
    '</div>',
]);
t.compile();
t.append('some-element', {id: 'myid', cls: 'myclass', name: 'foo', value: 'bar'});

Ext.AbstractComponent

如下圖,Ext.AbstractComponent是許多元件的共同祖先,提供了許多元件共同的基本行為,像

其有幾個特別需要提及的

  1. getEl()
  2. getPlugin()
  3. getXTypes()

事件處理

Ext.util.Observable是所有事件處理的根基。

var el = Ext.get('myDiv');
el.on('click', clickHandle(){});

TBD

  • Ext.Function.bind 將前一次的function的傳回值當作參數傳入下一次的呼叫 (有functional programming的味道)
  • Ext.Function.pass 建立一個新的function,用來取代舊function但改變scope
  • Ext.Function.defer 延遲一段時間後,進行function call

Resource