DOJO官方API翻译或解读-dojo/store (自定制存储器)

时间:2021-11-29 16:50:33

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(参数)可能包括下面这些属性,均是可选的:

  • start - 启动偏移值

  • count - 返回的对象数

  • sort - 排序属性数组,attribute 指示一个用作排序的属性值,descending指示该属性是否为倒序。

    For example: [{attribute:"price", descending:true}]. 如果排序参数被省略,那么会按照自然顺序,如果存在一个自然序列。

put(object, options)

保存一个对象(object参数),参数options是可选的,可能有下列值(每一个值都是可选的):

  • overwrite -代表是保存该对象时,是否可以覆盖已经存在的对象。当false时,不会去覆盖已经存在的对象,而是会创建一个新的对象,(此处新建处理和add()方法一致)默认情况下,覆盖与否都有可能。
  • before -如果store里的对象有一个自然顺序,该参数会指定保存的这个对象放的位置,为之前第几个。当此值为空时,对象被存放在最后。
  • parent - 如果store是单亲结构,该参数指定保存的对象的父(母)是哪个。
  • oldParent -如果store是有父的分层结构下,改值可以指下原先的父对象,因此可以删除前向链接。
add(object, options) 创建一个新对线,option参数同put()
remove(id) 通过ID删除对象
getIdentity(object) 反回该对象的ID,该方法必定是同步的。
queryEngine(query, options)

通过一个query查询,返回一个函数,该函数可以基于一个javascript数组执行这个查询"query"。

改方法可以代替提供更复杂的查询能力,返回的查询函数可以拥有匹配属性,如果该查询被一个对象匹配。

ThequeryEngine may be replace to provide more sophisticated querying capabilities. The returned query function may have amatches property that can be used to determine if an object matches the query.

transaction()

开始事务并返回一个事务对象。

事务对象包括以下:

  commit() - 在事务中发生的所有变化都提交

  abort() - 在事务中发生的所有变化都放弃

注意一个store用户可能不会在使用put,delete等方法前调用transaction(),在这些操作被认为“auto-commit”风格时。

同时,在一个事务中,通知事件是即时的,紧跟着提交操作。也因此,丢弃一个事务,可能要求发送一个新的通知事件去通知数据的回降。  

getChildren(object, options)

Returns the children of an object. The options parameter may include the same properties as query() options.

返回一个对象的儿子,配置参数和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);
 
  • The object 参数指示对象是被创建,修改或者删除。
  • The removedFrom 参数指示结果数组里的一个索引,该索引指示对象原来的地方。如果值为-1,则代表对结果数组而言是新添加的对象。
  • The insertedInto 参数指示结果数组里的一个索引,该索引指示对象现在的地方,如果值为-1,则代表对象被移出结果数集。

参数includeObjectUpdates 指示受否包括那些不影响对象顺序的更新。如果该值不被设为true,那些不涉及添加,移除,修改顺序的改变,不会触发这个listener。

close() 结果集调用该方法后,listener(监听器)不再生效。
 

Modules

下列的存储器(store),存储器的包(store wrapper) 和工具,都是dojo库的一部分。这些提供了一个坚实的基础去构建一个使用存储器的组件,进一步可以去构建更加复杂的存储技术模块。下列的两个核心存储器,是基于经典的内存和服务器的模式的存储器。(in-memory and server-based)

在新的API中,同样有一个适配存储器,用于兼容旧的dojo/data存储器。

同时,有一个适配存储器允许你以旧的dojo/data存储器来使用新的dojo/store的API:

我们正在将方向转向,通过提供存储器包或者存储器中间件来提供组合的存储器功能。其中几个关键的存储器包:

  • dojo/store/Observable

    增强存储器的数据检测能力,增加一个observe方法在查询结果集,该方法会通知数据变化。

  • dojo/store/Cache

    增加存储器的缓存能力,于是一个基本存储器不需要处理缓存问题的能力。

通过一个可以轻易混合和匹配的包,基本存储器实现各种功能。一个常见的模式可能会是这样: 

require(["dojo/store/Memory", "dojo/store/Observable"], function(Memory, Observable){
var store = Observable(new Memory({ data: someData }));
});

下面还有两个工具模块:

  • dojo/store/util/SimpleQueryEngine

    这是基础的查询引擎(query engine),提供了简单对象哈希表(散列表)过滤器和基于函数的过滤器。

  • dojo/store/util/QueryResults

    这个工具会使用一个数组或者一个带数组返回的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对象,因此可以通过经典方法去访问和修改值。

See Also