dojo/store 是對已存數據的訪問和存儲的統一接口,dojo/store意圖以一個簡單、易於使用和擴展的API來,替代、集合和改善 dojo/data 和dojox/storage 。基於HTML5/W3C’s IndexedDB object store API. 原先的dojox/storage 已經被Dojo object store Api兼容。
API
Methods
該API下所有的方法都是可選的,所有的方法都會返回一個promise。(部分在w3c的object store API內還未定論是否提供promise)
(博主:promise可以指派方法做執行成功/失敗的回調)
方法名 | 描述 |
---|---|
get(id) | 通過ID檢索對象,返回該對象。 |
query(query, options) | 使用提供的query(參數)對store進行查詢 返回值為一個數組或者一個promiss, 該promise 必有forEach()、map()、filter()、reduce(),可選的close() 該promise 必有total屬性(total同時也可以是promise); options(參數)可能包括下面這些屬性,均是可選的:
|
put(object, options) | 保存一個對象(object參數),參數options是可選的,可能有下列值(每一個值都是可選的):
|
add(object, options) | 創建一個新對線,option參數同put() |
remove(id) | 通過ID刪除對象 |
getIdentity(object) | 反回該對象的ID,該方法必定是同步的。 |
queryEngine(query, options) | 通過一個query查詢,返回一個函數,該函數可以基於一個javascript數組執行這個查詢"query"。 改方法可以代替提供更復雜的查詢能力,返回的查詢函數可以擁有匹配屬性,如果該查詢被一個對象匹配。 The |
transaction() | 開始事務並返回一個事務對象。 事務對象包括以下: commit() - 在事務中發生的所有變化都提交 abort() - 在事務中發生的所有變化都放棄 注意一個store用戶可能不會在使用put,delete等方法前調用transaction(),在這些操作被認為“auto-commit”風格時。 同時,在一個事務中,通知事件是即時的,緊跟着提交操作。也因此,丟棄一個事務,可能要求發送一個新的通知事件去通知數據的回降。 |
getChildren(object, options) | Returns the children of an object. The 返回一個對象的兒子,配置參數和query()一致。 |
getMetadata(object) | 返回元表數據。 可能包括attribution, cache directives, history, or version information. |
Properties
屬性 | 類型 | 描述 |
---|---|---|
idProperty | String | 用來做ID的屬性名 |
data | Array of Objects | 如果該store擁有一個緩存對線集合,這個屬性可以使之生效。該屬性只是引用,所以一個額外的層可以在對象刪除時,被完整地清楚掉。 |
Returned Objects
從dojo/store中返回的對象主要被當作普通的hash對象,並且擁有標准的javascript屬性來接入他們的數據庫和修改他們。無論如何,store返回的對象也會有定義的方法,這些方法並不是他們自己的屬性(調用hasOwnProperty(methodName)會返回false),但會是從其中那個一個屬性里繼承來。這可以確保枚舉數據屬性的簡易性。通常,一個store會選擇返回的對象,是 dojo/Stateful 的實例。
Observing Result Sets
當一個store被dojo/store/Observable包裹着時,通過對結果集observe方法,可以監聽數據的變化。(結果集是query的返回),observe方法介紹如下:
方法 | 描述 |
---|---|
observe(listener, includeObjectUpdates) | 參數listener是一個函數,這個函數有以下參數: listener(object, removedFrom, insertedInto);
參數 |
close() | 結果集調用該方法后,listener(監聽器)不再生效。 |
Modules
下列的存儲器(store),存儲器的包(store wrapper) 和工具,都是dojo庫的一部分。這些提供了一個堅實的基礎去構建一個使用存儲器的組件,進一步可以去構建更加復雜的存儲技術模塊。下列的兩個核心存儲器,是基於經典的內存和服務器的模式的存儲器。(in-memory and server-based)
-
一個內存對象,用於保存查詢(結果),以及修改、訪問客戶端內存數據。這可以僅僅由一個簡單的javascript數組創建而成。
-
一個面向服務器的JSON/REST對象,通過REST(Representational State Transfer)式的http請求,來保存查詢,以及修改、訪問數據。這將實現 dojox/data/JsonRestStore,dojox/data/QueryReadStore 和 dojox/data/ServiceStore.的概念和功能。
在新的API中,同樣有一個適配存儲器,用於兼容舊的dojo/data存儲器。
同時,有一個適配存儲器允許你以舊的dojo/data存儲器來使用新的dojo/store的API:
我們正在將方向轉向,通過提供存儲器包或者存儲器中間件來提供組合的存儲器功能。其中幾個關鍵的存儲器包:
-
增強存儲器的數據檢測能力,增加一個observe方法在查詢結果集,該方法會通知數據變化。
-
增加存儲器的緩存能力,於是一個基本存儲器不需要處理緩存問題的能力。
通過一個可以輕易混合和匹配的包,基本存儲器實現各種功能。一個常見的模式可能會是這樣:
require(["dojo/store/Memory", "dojo/store/Observable"], function(Memory, Observable){ var store = Observable(new Memory({ data: someData })); });
下面還有兩個工具模塊:
-
dojo/store/util/SimpleQueryEngine
這是基礎的查詢引擎(query engine),提供了簡單對象哈希表(散列表)過濾器和基於函數的過濾器。
-
這個工具會使用一個數組或者一個帶數組返回的promise,並且返回一個結果集對象,該結果集對象擁有標准的迭代方法(
forEach()
,map()
, andfilter()
)
Design
Notification Rational
使用dojo/store里的通知體系(observe),來代替以前dojo/data的通知體系(基於事件),是為了解決幾個dojo/data通知體系的問題。
首先,他忽略了一個事實,大部分時間用戶只需要監聽子集的事件,而且訂閱事件是昂貴的。另一方面,在客戶端的訂閱事件花費很少,全權委托(carte blanche 彗星式派發事件)訂閱事件在服務端是非常昂貴的,它強迫服務端發送過多的事件,同時強迫客戶端去過濾事件。
同時,事件訂閱可以解決一個問題,如果我們使用窗口不理解的方式(這些操作對窗體不透明)去創建或者改變項目時,經常會出現。用grid舉一個例子,所有onNew,會增加一行,無論這個增加的新項目是否匹配到查詢。而grid它自己完全不知道查詢是如何工作的,所以它不能過濾掉這些事件(例如onNew)。現在通過在“查詢動作“本身加入通知,通知根據他們如何影響一個給定的查詢結果集,可以被解釋。(該查詢結果集才是窗口最終關心的)
不同的事件名被使用來清晰區分與dojo/data 通知語法的區別。因為影響了查詢結果集(無論他們是否已經加入,或者是從一些已存在的查詢中出走。),一些獨特的事件被定義。同時,onUpdate()被適用於一整個對象,而不是其中的單獨的某個屬性。
Design Goals
- 人們可以很輕易地實施自己的存儲對象,基本上可以很簡單地寫些什么去與服務器交互,而不需要處理很多dojo/request 調用。更高級的功能可以基於此建立。對於這個策略而言,一個關鍵點就是非常簡單的API,這要求一個最小所需復雜度來實施。
- 維持與dojo/data提供的功能一樣的等級。一個存儲對象,雖然API所要求必須實施的代碼量很少,但有很多部分的代碼是可以實施來增強存儲器的功能的。可選功能是通過特征檢測(檢查方法是否存在)來判定是否有效的。擁有很多的可選配置,會將一些實現復雜性從存儲器轉移者處轉移到其它開發人員上,那些希望使用復雜功能的開發人員。無論如何,窗體是最普遍的存儲器使用者,而且大部分的開發人員都是使用一個已知配置,已知道功能的存儲器。通常,如果他們知道他們正在使用一個同步存儲器,與存儲器的交互將會變得非常簡單。每一個方法都應該是可選的,而且一個方法的實現標識着支持一個功能。還有,通常要求至少要實現get() 和 query()方法,一個存儲器如果沒有讀的能力就太弱了,這是顯而易見的。
- 每一個方法都可以用同步或者異步來實現。異步和同步的接口是一致的,區別是同步返回結果,異步返回承諾(promise)。接口要求不能調用其它已知的特定回調(沒理解)。
- 通過query 或者 get 從數據返回的對象,必須是一個標准的javasScript對象,因此可以通過經典方法去訪問和修改值。