最近研究了一些,也翻譯了一些,貼出來和大家分享。dojo的更多內容可以上: www.dojocn.cn 上查看。
一下內容是原創,轉載請註明:
dojo.data 是什麼?
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
dojo.data 是一個統一的數據訪問層,它沒有數據庫驅動的概念,只是一個統一的數據格式.
所有的數據被表現成一個 item 的 子item 或者 attribute , 由於這樣,數據就能夠被統一的方式訪問.
爲了直接拿來就可以用,dojo.data提供了一個基礎的 JsonItemStore 去讀一個特定格式的JSON 數據.
DojoX 這個項目(或者說是模塊)提供了更多的 stores (比如:XmlStore , CsvStore , OmplStore),這些stores可以解決服務器提供的對應的這些格式的數據.
此外,dojo.data是一個其他用戶可以重寫的API,這個概念類似java中的接口,因此,你可以編寫一個定製數據格式的dojo.data的一個子集.
當你的定製好自己的特定格式,而且按照dojo.data的規範來做,widgets 就可以直接知道你的datastore,並且其他的程序可以讀取你的數據,而不用瞭解你的特定格式.
dojo.data的最終目標是提供一個易用靈活的API集,就像interfaces.使datastore按照統一的格式被定製或者重寫.
按照標準接口寫的store就能夠被多樣的廣泛的應用程序或者widget等等使用.
本質上,API隱藏了特定格式的數據,這些格式在JSON,XML,Csv或者其他數據格式,並且提供了一個一致的讀item的attribute的方法,並且,用戶可以根據實際的使用情況定製最優化的方法讀取數據.(這一句翻譯的不好)
你可以理解dojo.data是dojo.xhrGet()(這個封裝了XMLHttp發送請求到服務器)上的一層,他們都是不用刷新頁面的異步操作.但是xhrGet將能夠讀取任何MIME類型的數據並且一下子都返回,然後就依靠store去翻譯這些數據成需要的格式,從而形成一般的讀取模型.
綜上:dojo.data提供了一套統一的讀取數據的方法,它的目的就是提供一個標準,大家按照這個標準來開發讀取數據的方法.
dojo.data對頁面組件關係非常密切,比如Tree和Combox都使用了store做爲數據源.所以學好這個對靈活使用widget很有幫助
=========================================================================================================================
dojo.data 術語
dojo.data 術語類似關係型數據庫術語,下面比較和對比了dojo.data術語和關係型數據庫的術語:
dojo:datastore
db:cursor
描述:js對象通過dojo.data APIs從data source讀取數據並且使 data item可用
dojo術語:data sorece
db術語:table
描述:這是保存原始數據的地方,比如:一個CsvStore數據源可能是.csv格式的文件,通常,data source是一個文件或者是個數據庫服務器,或者是一個webservice或其他
dojo術語:item
db術語:row
描述:data item有很多屬性,這些屬性都有值
dojo術語:attribute
db術語:column
描述:一個item的域或者屬性.
dojo術語:value
db術語:-
描述:屬性的內容
dojo術語:reference
db術語:-
描述:一個item指向另一個item的值
dojo術語:identity
db術語:primary key
描述:主鍵
dojo術語:query
db術語:Where字句
描述:讀取數據的條件.注意:非常建議所有的store使用attribute的name/value成對的結構,作爲查詢的格式連接stores.
internal data representation:一個私有的數據結構,datastore用它來緩存數據到客戶端,比如XML DOM節點,匿名JSON對象或者數組
dojo術語:request
db術語:Sql Select
描述:一個用來篩選item的參數,包括query,篩選attributes ,大小寫的限制和回調函數
=============================================================================================================================
www.dojocn.cn 轉載請註明
dojo.data 設計和編程接口
在直接學習dojo.data的API之間,在研究API之前的基本概念必須先探究一下,因爲一些設計上的決定被選擇,但卻沒有解釋爲什麼選擇它們,可能會使這個設計看上去很奇怪。因此,在研究api細節之前,先完整的閱讀這些概念:
概念1:數據訪問被分成分離的APIs,store可以有選擇的實現這些API
數據訪問被破壞成分離的APIs,因爲不是所有的服務和數據回傳都需要所有的訪問或者函數。因此不是所有的datastore能夠實現比如read,write,identify,notifications這樣的函數(注意這裏的函數是js的function,在這裏可以想像成java的接口)。
爲了能夠簡單的就知道這個store提供什麼特性,每一個store必須提供getFeatures()這個函數,這個函數報告出這個store使用了哪些APIs。
下面是基礎的APIs定義:
dojo.data.api.Read:能夠從一個dataitems裏讀取子items和attribute。而且可以查詢,排序,過濾數據。
dojo.data.api.Write:能夠生成、刪除、更新dataitems和attribute。不是所有的服務都允許修改數據項的。實際上,大多數公共的服務,比如:Flikr,Delicious還有googleMaps都只是提供讀取服務。
dojo.data.api.Identity:能夠通過唯一標識定位查找一個數據項,不是所有的數據服務有唯一標識的。
dojo.data.api.Notification:能夠將發生在store上的數據修改事件通知給監聽器。基礎的功能是那些生成、刪除、更新一個數據項的事件。對於像定期將數據更新的事件通知backend服務有顯著的用處。
將來的一些特性:
下面的特性是一些dojo開發團體將會定義的額外的特性,這些都還沒有完全明確,並且還在開發中。因此,他們沒有被提供在當前版本的開發包中。注意啊,下面的列表可能隨時變化。
dojo.data.api.Schema
dojo.data.api.Attribution
dojo.data.api.Versioning
dojo.data.api.Derivation
www.dojocn.cn 轉載請註明
概念二:數據項和數據項的屬性經常通過store的函數來訪問,修改,創建和刪除,而從來不直接訪問。
這個概念就是防止dojo.data在最初的時候表現出來混亂,下面的例子顯示了這個概念:
---------------------------------------------------------------------------------
var store = new some.data.Store();
var items;
.......
//假設這時items已經通過store.fetch()得到了數據,成爲了array
//爲了列舉出這個數組的值,你要這樣做:
for(var i=0;i<items.length;i++){
var item=items[i];
console.log("For attribute 'foo' value was:["+store.getValue(item,"foo")+"]");
}
----------------------------------------------------------------------------------
爲什麼不像下面這樣做呢?
var value=item["foo"];
var value=item.foo;
var value=item.getValue("foo");
爲什麼這是dojo.data必須要求的呢?下面是原因:
1、訪問效率。通過store的函數訪問,store可以隱藏item的內部結構,無論在什麼特殊形式下的數據格式,item都能保持一個格式.比如:
item可能是一個XML元素,這種情況下,當調用store.getValue()時store將使用DOM的API來訪問數據;另外一種情況下,如果item是個一個javascript結構,那麼store將通過javascript的訪問符號來訪問數據.從最終用戶的角度來看,這個訪問都是一樣的:store.getValue(item,"attribute"),因此提供了一個統一的感觀去訪問多樣的類型數據.通過減少item的加載次數,也提高了訪問item的效率,因爲你不用每次都轉換格式了.
2、store可以使用非常簡潔的內部結構。這大大減少了程序員記憶每種數據格式的工作量。
3、能夠提供懶加載的模式
=======================================================================================
The Read API
Dojo.data 中最基礎的API(或者說是接口)就是Read API. 所有的Store都必須實現這個接口,因爲所有的store都需要獲取和處理item(數據項)。針對處理數據項,Read API被設計的非常靈活。Read API提供如下的功能:
l 查看datastore都實現了那些接口,具有什麼功能。通過getFeatures()方法。
l 查看一個item所包含的所有屬性而不需要了解這個item的格式。getAttributes(item)方法
n 比如:一個item記錄着一個學生的信息。通過getAttribuets()方法,你能得到這個學生包括哪些信息,比如:姓名,學號,等等。
l 獲取item的屬性的值,而不用知道item的格式。
n Item的保存格式有很多中,有json或者csv或者數據庫中保存。通過getValue方法,你就能得到一個item的屬性的值,轉換數據格式交給store來做。
l 查看所有的items的屬性,看看有沒有指定的值。
l 驗證一個js Object是不是store產生的item.
l 查看一個item是不是被完全加載了,還是僅僅是一個需要被加載的根(stub). isItemLoaded()
l 加載一個stub item ,這個方法就是懶加載的時候使用的。loadItem()
l 通過一些查詢條件來查詢items
l 給一些items排序
l 爲一個查詢結果分頁。(我覺得對非數據庫型的查詢也許會有用一些,至少能使操作方便一些吧)
l 通過通配符( * 和 ? )來過濾查詢結果
www.dojocn.cn 轉載請註明
一些例子:
1、 查看一個store支持那些APIs
var store = new some.Datastore();
var features = store.getFeatures();
for(var i in features){
console.log("Store supports feature: " + i);
}
2、 測試一個對象是不是一個item
var store = new some.Datastore();
if(store.isItem(someObject)){
console.log("Object was an item.");
}else{
console.log("Object was NOT an item.");
}
3、 列舉一個item的所有屬性
var store = new some.Datastore();
...
//Assume that someItem is an item we got from a load.
var attributes = store.getAttributes(someItem);
for(var i = 0; i < attributes.length; i++){
console.log("Item has attribute; " + attributes[i]);
}
4、 測試一個item是否包含特定的屬性
var store = new some.Datastore();
...
//Assume that someItem is an item we got from a load.
var attributes = store.getAttributes(someItem);
for(var i = 0; i < attributes.length; i++){
console.log("Item has attribute; " + attributes[i]);
}
5、 得到一個item的label
var store = new some.Datastore();
...
//Assume that someItem is an item we got from a load.
var label = store.getLabel(someItem);
console.log("item has label: " + label);
//其實一個item的label也是一個item的屬性,只不過是一個特殊的屬性。在json的開始部分:label:”name” 這個就聲明瞭,item的name屬性就是item的label,所以通過getLabel就得到了name屬性,也就等同於getValue(item,”name”);
6、得到一個store的所有數據
var pantryStore = new dojo.data.JsonItemStore({url: "pantry_items.json" } );
//Define the onComplete callback to write COMPLETED to the page when the fetch has finished returning items.
var done = function(items, request){
document.appendChild(document.createTextNode("COMPLETED"));
}
//Define the callback that appends a textnode into the document each time an item is returned.
gotItem = function(item, request) {
document.appendChild(document.createTextNode(pantryStore.getValue(item, "name"));
document.appendChild(document.createElement("br"));
}
//Define a simple error handler.
var gotError = function(error, request){
alert("The request to the store failed. " + error);
}
//Invoke the search
pantryStore.fetch({onComplete: done, onItem: gotItem, onError: gotError});
//這裏onComplete和onItem同時使用的時候onComplete的items參數是null,這點請注意。
6、 通過一個標識得到一個item
var pantryStore = new dojo.data.JsonItemStore({url: "pantry_items.json" } );
var pepperItem = pantryStore.getItemByIdentity("pepper");
if (pepperItem !== null){
alert('Pepper is in aisle ' + pantryStore.getValue(pepperItem,"aisle");
}
//這個標識在json的開頭部分有聲明, identifier: 'name' ,也就是說item的name屬性是標識。
7、 通過條件獲取數據
jsonItemStore.fetch({
queryOptions: {ignoreCase: true}, //忽略大小寫
query: { name: "*pepper*", aisle: "Spices" }, //name 和 aisle是屬性的名稱
onComplete:
...
});
8、 嵌套定義item
一個item可以包括多個子item就像一棵樹一樣。使用reference可以關聯子節點。通過getValues()方法可以得到孩子節點的數組。
9、 分頁
var store = new dojo.data.JsonItemStore({url: "pantryStore.json" });
var pageSize = 10;
var request = null;
var outOfItems = false;
var onNext = function(){
if(!outOfItems){
request.start += pageSize;
store.fetch(request);
}
};
var onPrevious = function(){
if (request.start > 0){
request.start -= pageSize;
store.fetch(request);
}
}
var itemsLoaded = function(items, request){
if (items.length < pageSize){
outOfItems = true;
}else{
outOfItems = false;
}
...
}
request = store.fetch({onComplete: itemsLoaded, start: 0; count: pageSize});
10、 排序
var store = new dojo.data.JsonItemStore({url: "pantryStore.json"});
var sortKeys = [
{attribute: "aisle", descending: true},
{attribute: "name", descending: false}
];
store.fetch({
sort: sortKeys;
onComplete:
...
});
//When onComplete is called, the array of items passed into it
//should be sorted according to the denoted sort array.
www.dojocn.cn 轉載請註明