和甘特圖打交道,就不得不和DataStore打交道,甘特圖中的資料是存放類型為Store 的資料存儲器中,通過指定甘特圖中的store 屬性來設定表格中顯示的資料,通過調用store 的load 或reload方法可以重新加載表格中的資料。ExtJS 中用來定義控件中使用資料的API 位于Ext.Data 命名空間中,本附錄我們重點對ExtJS 中的資料存儲Store 進行介紹。
首先需要明确是,ExtJS 中有一個名為Record 的類,表格等控件中使用的資料是存放在Record 對象中,一個Record 可以了解為關系資料表中的一行,也可以稱為記錄。Record 對象中即包含了記錄(行中各列)的定義資訊(也就是該記錄包含哪些字段,每一個字段的資料類型等),同時又包含了記錄具體的資料資訊(也就是各個字段的值)。
我們來看直接使用Record 的代碼:
1. var MyRecord = Ext.data.Record.create([
2. {name: 'title'},
3. {name: 'username', mapping: 'author'},
4. {name: 'loginTimes', type: 'int'},
5. {name: 'lastLoginTime', mapping: 'loginTime', type: 'date'}
6. ]);
7. var r=new MyRecord({
8. title:"日志标題",
9. username:"easyjf",
10. loginTimes:100,
11. loginTime:new Date()
12. });
13. alert(MyRecord.getField("username").mapping);
14. alert(MyRecord.getField("lastLoginTime").type);
首先使用Record 的create 方法建立一個記錄集MyRecord,MyRecord 其實是一個類,該類包含了記錄集的定義資訊,可以通過MyRecord 來建立包含字段值的Record 對象。在上面的代碼中,最後的幾條語句用來輸出記錄集的相關資訊,MyRecord.getField("username")可以得到記錄中username 列的字段資訊,r.get("loginTimes")可以得到記錄loginTimes 字段的值,而r.data.username 同樣能得到記錄集中username 字段的值。
對Record 有了一定的了解,那麼要操作記錄集中的資料就非常簡單了, 比如r.set(name,value)可以設定記錄中某指定字段的值,r. dirty 可以得到目前記錄是否有字段的值被更改過等等。
Store 可以了解為資料存儲器,可以了解為用戶端的小型資料表,提供緩存等功能。在ExtJS 中,GridPanel、ComboBox、DataView 等控件一般直接與Store 打交道,直接通過store來獲得控件中需要展現的資料等。一個Store 包含多個Record,同時Store 又包含了資料來源,資料解析器等相關資訊,Store 通過調用具體的資料解析器(DataReader)來解析指定類型或格式的資料(DataProxy),并轉換成記錄集的形式儲存在Store 中,作為其它控件的資料輸入。
資料存儲器由Ext.data.Store 類定義,一個完整的資料存儲器要知道資料源(DataProxy)及資料解析方式(DataReader)才能工作,在Ext.data.Store 類中資料源由proxy 配置屬性定義、資料解析(讀取)器由reader 配置屬性定義,一個較為按部就班建立Store 的代碼如下:
7. var dataProxy=new Ext.data.HttpProxy({url:"link.ejf"});
8. var theReader=new Ext.data.JsonReader({
9. totalProperty: "results",
10. root: "rows",
11. id: "id"
12. },MyRecord);
13. var store=new Ext.data.Store({
14. proxy:dataProxy,
15. reader:theReader
16. });
當然,這樣的難免代碼較多,Store 中本身提供了一些快捷建立Store 的方式,比如上面的示例代碼中可以不用先建立一個HttpProxy,隻需要在建立Store 的時候指定一個url 配置參數,就會自動使用HttpProxy 來加載參數。比如,上面的代碼可以簡化成:
7. var theReader=new Ext.data.JsonReader({
8. totalProperty: "results",
9. root: "rows",
10. id: "id"
11. },MyRecord);
12. var store=new Ext.data.Store({
13. url:"link.ejf",
雖然不再需要手動建立HttpProxy 了,但是仍然需要建立DataReader 等,畢竟還是複雜,ExtJS 進一步把這種常用的資料存儲器進行了封裝,在Store 類的基礎上提供了SimpleStore、SimpleStore、GroupingStore 等,直接使用SimpleStore,則上面的代碼可以進一步簡化成下
面的内容:
1. var store=new Ext.data.JSonStore({
2. url:"link.ejf?cmd=list",
3. totalProperty: "results",
4. root: "rows",
5. fields:['title', {name: 'username', mapping: 'author'},
6. {name: 'loginTimes', type: 'int'},
7. {name: 'lastLoginTime', mapping: 'loginTime', type: 'date'}
8. ]
9. });
DataReader 表示資料讀取器,也就是資料解析器,其負責把從伺服器或者記憶體數組、xml文檔中獲得的雜亂資訊轉換成ExtJS 中的記錄集Record 資料對象,并存儲到Store 裡面的記錄集數組中。
資料解析器的基類由Ext.data.DataReader定義,其它具體的資料解析器都是該類的子類,ExtJS 中提供了讀取二維數組、JSon 資料及Xml 文檔的三種資料解析器,分别用于把記憶體中的二級數組、JSON 格式的資料及XML 文檔資訊解析成記錄集。下面簡單的介紹:
Ext.data.ArrayReader-數組解析器,用于讀取二維數組中的資訊,并轉換成記錄集Record
對象。首先看下面的代碼:
2. {name: 'title', mapping:1},
3. {name: 'username', mapping:2},
4. {name: 'loginTimes', type:3}
5. ]);
6. var myReader = new Ext.data.ArrayReader({
7. id: 0
8. }, MyRecord);
這裡定義的myReader 可以讀取下面的二維數組:
1. [ [1, '測試', '小王',3], [2, '新年好', 'williamraym',13] ]
Ext.data.JsonReader-Json 資料解析器,用于讀取JSON 格式的資料資訊,并轉換成記錄集Record 對象。看下面使用JsonReader 的代碼:
4. {name: 'loginTimes', type: 'int'}
6. var myReader = new Ext.data.JsonReader({
7. totalProperty: "results",
8. root: "rows",
9. id: "id"
10. }, MyRecord);
這裡的JsonReader 可以解析下面的JSON 資料:
1. { 'results': 2, 'rows': [
2. { id: 1, title: '測試', author: '小王', loginTimes: 3 },
3. { id: 2, title: 'Ben', author: 'williamraym', loginTimes:13} ]
4. }
JSonReader 還有比較特殊的用法,就是可以把Store 中記錄集的配置資訊存放直接儲存在從伺服器端傳回的JSON 資料中,比如下面的例子:
1. var myReader = new Ext.data.JsonReader();
這一個不帶任何參數的myReader,可以處理從伺服器端傳回的下面JSON 資料:
1. {
2. 'metaData': {
3. totalProperty: 'results',
4. root: 'rows',
5. id: 'id',
6. fields: [
7. {name: 'title'},
8. {name: 'username', mapping: 'author'},
9. {name: 'loginTimes', type: 'int'} ]
10. },
11. 'results': 2, 'rows': [
12. { id: 1, title: '測試', author: '小王', loginTimes: 3 },
13. { id: 2, title: '新年好', author: 'williamraym', loginTimes:13}]
14. }
Ext.data.XmlReader-XML 文檔資料解析器,用于把XML 文檔資料轉換成記錄集Record對象。看下面的代碼:
6. var myReader = new Ext.data.XmlReader({
7. totalRecords: "results",
8. record: "rows",
上面的myReader 能夠解析下面的xml 文檔資訊:
1. <topics>
2. <results>2</results>
3. <row>
4. <id>1</id>
5. <title>測試</ title >
6. <author>小王</ author >
7. <loginTimes>3</ loginTimes >
8. </row>
9. <row>
10. <id>2</id>
11. <title>新年好</ title >
12. <author> williamraym </ author >
13. <loginTimes>13</ loginTimes >
14. </row>
15. </topics>
DataProxy 字面解釋就是資料代理,也可以了解為資料源,也即從哪兒或如何得到需要交給DataReader 解析的資料。資料代理(源)基類由Ext.data.DataProxy 定義,在DataProxy的基礎,ExtJS 提供了Ext.data.MemoryProxy、Ext.data.HttpProxy、Ext.data.ScriptTagProxy
等三個分别用于從用戶端記憶體資料、Ajax 讀取伺服器端的資料及從跨域伺服器中讀取資料等三種實作。
比如像SimpleStore 等存儲器是直接從從用戶端的記憶體數組中讀取資料,此時就可以直接使用Ext.data.MemoryProxy , 而大多數需要從伺服器端加載的資料直接使用Ext.data.HttpProxy,HttpProxy 直接使用Ext.Ajax 加載伺服器的資料,由于這種請求是不能跨域的,是以要要讀取跨域伺服器中的資料時就需要使用到Ext.data.ScriptTagProxy。
在實際應用中,除了基本的從記憶體中讀取javascript 數組對象,從伺服器讀取JSON 數組,從伺服器取xml 文檔等形式的資料外,有時候還需要使用其它的資料讀取方式。比如熟悉EasyJWeb 中遠端Web 腳本調用引擎或DWR 等架構的都知道,通過這些架構我們可以直接在用戶端使用javascript 調用伺服器端業務元件的方法,并把伺服器端的結果傳回到用戶端,用戶端得到的是一個javascript 對象或數組。由于這種方式的調用是異步的,是以,
相對來說有點特殊, 即不能直接使用Ext.data.MemoryProxy , 也不能直接使用Ext.data.HttpProxy,當然更不需要Ext.data.ScriptTagProxy,這時候就需要建立自定義的DataProxy 及Store,然後使用這個自定義的Store 來實作這種基于遠端腳本調用引擎的架構得到資料。