本文翻译自: Dojo Object
Stores
原作者: Kris Zyp
翻译: Siqi
Dojo 1.6推出了一套新的名为Dojo Object Store的data store API。 这套基于HTML5 IndexedDB object
store API
的新store API旨在大大简化Dojo store的交互和构建。
这套新的API遵循HTTP/REST命名规范,并与dojox.storage
providers
(local storage, cookie storage, 和 WebSQL
storage适用)以及其他所有符合这些开放标准的库兼容。
以下是这套新store API的几条核心理念:
-
用户界面与数据分离
– 这长久以来都是我们data API的设计目标。
这些API帮助我们将用户界面与数据分离,从而使得我们可以对widgets或者data providers进行独立的改进。
-
简单至上
–
你可以简单地创建一个带有query()和get()方法的对象实例,这些方法的返回值为objects,这个对象实例便是一个可用的store。当你想要添加别的功能时,例如创建新的对象,你可以添加一个add()方法,同样的,你可以为更新对象功能引入一个put()方法。
-
简单JavaScript对象
– 这套新的object store
API使用简单JavaScript对象而不是不透明项(opaque
items)。在通过get()方法返回一个对象或是query()返回一个对象数组时,你可以使用for-in循环来访问这些对象中的属性。保存对象只需要将一个简单对象传给put()方法就可以实现。
-
基于Promise
–
同步方法与异步方法的接口是基本相同的,唯一的区别是同步方法直接返回值而异步方法返回promise。任何方法都可以选择同步模式还是异步模式(返回promise)。由于不再需要回调函数,极大简化了与已知的同步store的交互。同时异步模式带来的困扰被从接口上分离了出来,大大简化了API。
-
功能清晰
–
不需要额外的方法来判断一个store的功能。如果你想知道是否可以向一个store添加新的对象,只需要检查它是否有add()方法;如果你想知道该store是否是可查询的,只需要检查它是否有query()方法。如果你想要创建一个只读的store,只需要实现一些读取函数(get,query,getIdentity)。
-
功能层次化
–
层次化的功能使得可以你可以从一个简单、轻量级的store开始,逐步添加你需要的功能。Dojo核心库配备了一个缓存封装器(caching
wrapper)(dojo/store/Cache)来提高性能,以及一个数据变化通知封装器(dojo/store/Observable)。这些store层次化的模块都是可选的并且可以将他们添加到任意store上。这使得我们可以将我们的核心store——dojo/store/Memory和dojo/store/JsonRest保持简单、轻量,并让使用者可以简单地创建新store。
Dojo Object Store
API是一套介于不同的数据提供者和数据消费者之间的接口。使用者可以使用这套接口实现任意store,而Dojo核心库本身配置了两个常用的核心store——dojo/store/Memory和dojo/store/JsonRest。
这是一个非常简单的常驻内存(in-memory)store。它对于快速创建一个store是非常有用的,
特别是对于较小的数据集。只要简单地提供一个数组作为数据源,便可以创建出一个Memory
store,之后你便可以开始对该store进行查询和交互。(更多使用细节请参见Memory object store
documentation
)
Memory store是一个同步模式的store,也就是说它直接返回值,这令它使用起来非常简单。例如:通过id来获得一个对象:
需要再次强调的是,这个新的object store返回的是简单的对象,所以我们可以很容易的获取其中的属性:
使用简单对象也使得更新store非常简单:
改进过的查询功能是Dojo object
stores的新功能之一。查询通过使用query()方法来实现,而返回的结果集提供一系列方便的迭代方法(interative
methods)——与dojo.query非常相似——同步模式和异步模式的sotre都提供此功能。因此我们可以使用forEach,map,或是filter方法来操作结果集。Memory
Store支持多种形式的查询。首先,我们可以通过键值匹配(name-value
matches)来进行查询(和Dojo.data中的ItemFileReadStore一样)。以下我们根据category进行查询:
键值匹配提供了一种简单的查询机制,但是有时需要更复杂的查询。Memory
store也接受函数来进行过滤,因此允许任意复杂查询。例如,查询所有价格低于10的产品:
我们也可以通过函数名来引用函数,其本质是引用store中同名的方法。
JsonRest
假定有一套服务器端的API存在,且该套API旨在与store进行交互。它实现了一个健壮的、符合标准的HTTP/REST客户端接口。dojo/store/JsonRest遵循REST高扩展性的原则,非常适合大数据集。JsonRest是一个异步模式的store,其所有异步方法返回promise(有一个列外:getIdentity方法永远是同步的)。
Json Rest object
store与HTTP兼容服务器交互的方式与dojox.data.JsonRestStore十分相似。然而,JsonRest在store
API重构的过程中已经得到了极大的简化。简单地提供一个链接到服务器的URL便可以创建出一个JsonRest store(更多使用细节请参见JsonRest object store
documentation
):
store = new dojo.store.JsonRest({target:"/Data/"});
store的方法十分直观,与HTTP方法相对应。store.get(“some-id”)会发送一个GET请求到/Data/some-id并返回一个promise/Deferred作为结果。例如:
store.remove(id)则会对应地发送一个DELETE请求。add(object)和put(object)也会同样触发相应的请求。如果传给put(object)(或add(object))的object带有identity属性,则将会发送一个PUT请求。如果object不含有id或是第二个参数(options)包含一个值为true的incremental属性,则将会发送一个POST请求。
如果options.overwrite为true的话,该请求会包含一个If-Match: *
header,若options.overwrite为false或是使用add(object)的话,则会包含一个If-None-Match:
*
header。这样的服务器之间的通信一般在创建或是更改对象时发生。
同步与异步的标准化
如果你在写一个同步异步皆有的store的话,我们推荐使用dojo.when()。由于then()方法仅当store方法是异步时才有效,因此这种情况下它并不值得完全依赖,我们可以使用dojo.when(),任何返回的值都将被恰当的处理。
dojo.when()方法可以被应用到所有store方法上。
除了核心store的实现,Dojo还配备了两个store封装器(wrappers)。第一个是dojo/store/Cache。这个封装器需要与两个store一起使用:一个caching
store和一个master store。一个典型的Cache封装器使用场景是将JsonRest作为master store, 将Memory
store作为客户端的caching store。这使得你可以利用JsonRest store来与服务器进行通信,使用Memory
store来进行缓存来避免不必要的HTTP请求。下面有一个例子来说明我们如何将它搭建起来:
现在我们可以使用我们整合了的store来执行一个查询。下面我们将查询所有的objects(我们可以省略查询条件来查询所对象):
这将使得返回结果被缓存在memory store中。之后我们可以通过get()方法来获取一个object而不需要额外发送一个HTTP请求:
通过put(),add()和remove()方法对数据进行的改变都将反应到被缓存的数据中。查询通常要求细粒度的应用程序来控制哪些数据需要被缓存,哪些不需要。因此,Cache
store不会尝试自动查询缓存。但是,如果你选择使用缓存进行查询的话,也没有问题。可以简单地查询caching
store,也就是我们例子中的memoryStore:
Dojo还配备了一个store封装器来增加对数据变化通知的支持。Dojo object store API和遗留的Dojo Data
API的通知机制十分不同。旧的API存在一个问题,通知是store层面的,因此要决定一个事件如何真正地影响一个渲染好的数据集是不可能的。
Dojo object
store通过将通知事件的监控绑定到查询的结果集上而不是store解决了这个问题。通过dojo/store/Observable模块,你可以包装一个store,而包装后的store得到的查询结果集都是“可监控的(observable)”。也就是说,query()方法返回的对象/数组/promise都有一个可以被用来监视结果集变化的observe()方法。参见Observable store wrapper
documentation for the exact signature of the observe() method and
callback
。
Observable
模块使得渲染一个结果集并实时根据底层数据的变化对界面进行更新变得非常容易。让我们来看一个例子。我们将根据存储的对象创建一个无序列表(<ul>)。首先,创建列表,然后我们将根据数据的变化做出反馈:
通过搭建起一个可以删除行和添加行的监控函数,我们基本上可以应对任何数据变化,包括添加、删除和更新。Observable模块甚至监控索引的更新,这使得如果结果集的排序顺寻发生变化了的话,更新的对象也可以被正确地移动到一个新索引指向的地方。同时请注意,在本例中,通过监听shoes结果集,我们只会获得符合条件的结果集中的相关更新。如果一个对象被更新、删除或是添加,并且它的category属性不是"shoe”,则没有通知时间会被发送给相应的监听器上。如果一个对象本来不是
“shoe”,之后被更新为一个"shoe”,这将触发一个向结果集添加数据的通知。如果一个对象本来是"shoe”在更新之后不再是”shoe”,这将触发一个从数据集中删除数据的通知。
Observable模块还会向store添加一个notify()方法。这对于Comet-driven的实时应用程序是非常有用的,因为它们会异步地从服务器接受更新并将其告知store(和所有store结果集上的监听器)。更多Dojo
1.6中Comet 和实时应用程序的相关细节请参见Dojo
Socket
。
与现存的Widget和Store协同工作
大多数Dijit widgets仍然基于遗留的Dojo Data API。但是,dojo配置了一个适配器(adapter)让使用者可以在基于Dojo
Data的widget上使用新的object store。dojo/data/ObjectStore
模块作为一个是配置器接受一个object
store并返回一个data store。Dojo还配置了一个可以让使用object store的widgets兼容遗留的data store的适配器。dojo/store/DataStore
模块接受一个data store并返回一个object store。
层级结构
object store API定义了一个用来实现层级结构的方法——getChildren(object, options)。getChildren
一般被一个父object调用,并返回其子元素集。getChildren的实现一般根据应用程序的需求来定制,但是也有很多常用的实现方式:
-
包含一个名为“children”
的子元素数组
–通过这种方法,每一个对象在一个数组中定义它的子元素,因此特意地保留了子元素的顺序。这种方法很适合较小的数据集。
-
包含一个父元素的引用
–通过这种方法,每一个对象定义其父元素,通过查询一个给定id的父元素下的所有对象便可以获得其所有的子元素。这种方法比较适合可能需要入分页或是排序等额外处理的大数据集
与其他Store兼容
因为store API是一个常用的模式,所以很多库的接口可以很容易的与store API兼容。dojox.storage providers
的接口和store API就很类似,除了put()写法有一点细微区别。可以很容易的将该方法进行转换:
或者我们可以将Jens Arps StorageJS
library
进行转换,其原本使用set()方法而不是put()方法:
StorageJS API还有一个allKeys()方法可以被转换成query()方法。
Object Stores
为了吸取dojo.data的精华并符合HTML5 IndexedDB标准,同时简化使用并使功能层次化,新的Dojo object
store构架被进行了彻底的重构。令人振奋的是现在我们终于可以使用这一新的手段来搭建我们的应用程序。同时我们很期待Dojo社区对于该设计的宝贵意见。
分享到:
相关推荐
- `dojo/`:Dojo库的核心文件和模块 - `dijit/`:Dojo的UI组件 - `dojox/`:扩展的Dojo模块 - `require.js`:Requirejs核心文件 - 可能还包括配置文件、项目特定的JavaScript模块和其他资源 解压这个压缩包,并按照...
dojo 1.6 api包含dojo、dojox、dijit等3个部分的api。
在Dojo 1.6版本中,DOM操作是其核心特性之一,它允许开发者高效地创建、修改和管理HTML元素。以下是对Dojo 1.6 DOM相关操作的详细说明: 1. **dojo.query**: 这是Dojo提供的一个强大选择器,类似于jQuery的`$`函数...
4. **Data Stores**:Dojo的数据存储API允许开发者与各种数据源进行交互,如XML、JSON、CSV等。1.6版的数据存储机制更加健壮,支持多种数据格式和远程数据源。 5. **DojoX**:Dojo eXtension是Dojo的扩展库,包含了...
标题中的"dojo v1.6 官方最新版同步下载.zip"指的是Dojo框架的1.6版本,这是一个官方发布的更新版本,可能包含了性能优化、新特性、修复的bug以及对之前版本的改进。 Dojo 1.6 版本主要知识点包括: 1. **模块系统...
<<Dojo的高级运用:Widget的制作>> 和 使用Dojo和JSON构建Ajax应用>> 中涉及到的源代码 博文链接:https://tailsherry.iteye.com/blog/102907
- **JavaScript库**:DOJO提供了许多JavaScript实用工具,如XMLHttpRequest的封装,使得异步通信(Ajax)更为便捷。 - **跨浏览器兼容**:DOJO的一个关键目标是消除不同浏览器之间的差异,确保代码在各平台上的兼容...
Dojo 是一个强大的JavaScript工具包,它为Web开发提供了丰富的功能和组件,涵盖了从DOM操作到数据管理,从动画效果到AJAX通信等各个方面。在Dojo 1.10版离线参考手册中,我们可以深入了解到这个版本的详细信息和使用...
2. **AMD 模块系统**: AMD是Dojo 1.6引入的重要特性,它允许异步加载JavaScript模块,解决了大型应用中因脚本顺序依赖导致的性能问题。require.js是基于AMD实现的一个知名库,而Dojo 1.6是最早采用这一模式的库之一...
Dojo 是一个强大的JavaScript工具库,它为Web开发提供了丰富的功能和组件,涵盖了从DOM操作、事件处理到AJAX通信、动画效果等各个方面。在深入理解Dojo之前,我们需要了解JavaScript在网页开发中的核心地位以及它...
1. **模块系统**:Dojo使用AMD(Asynchronous Module Definition)模块定义协议,允许异步加载模块。`require`和`define`是两个关键函数,`require`用于加载模块,`define`用于定义模块。 2. **dojo/_base**:这是...
Dojo 1.1.1版本提供了丰富的包资源,分为三个主要命名空间:Dojo、Dijit和DojoX。Dojo是核心功能包,Dijit包含所有Widget组件,而DojoX则用于实验性和扩展功能。 1. **Dojo** - `dojo.io`:提供了多种网络请求方法...
1. **Dojo核心模块**:Dojo的核心模块包括`dojo/_base`系列,如`dojo/_base/lang`用于语言扩展,`dojo/_base/array`提供数组操作方法,`dojo/_base/event`管理事件处理。了解这些基础模块,能帮助开发者更好地理解和...
1. **模块化系统(Dojo Loader)**:Dojo 1.2.3采用了AMD(Asynchronous Module Definition)规范,使得开发者可以异步加载和组织代码,提高页面性能,避免一次性加载整个库。`dojo.require` 和 `dojo.provide` 是...
1. **模块化系统**:Dojo 1.7 引入了AMD(Asynchronous Module Definition)模块加载机制,这允许异步加载JavaScript模块,优化了页面性能,避免了整体加载导致的阻塞。通过`require`和`define`函数,开发者可以轻松...
这种特性使得Dojo能更好地适应不同浏览器的差异,提高代码的可维护性和执行效率。 7. **dojo/on:** Dojo 1.7 引入了`on`事件处理函数,它提供了一个统一的事件监听API,支持DOM事件和自定义事件,使得事件处理更加...
Dojo 提供了上百个包,分别放入三个一级命名空间:Dojo、Dijit 和 DojoX。其中 Dojo 是核心功能包,Dijit 中存放的是 Dojo 所有的 Widget 组件,而 DojoX 则是一些扩展或试验功能。 常用的包包括: * dojo.io:...
9. **Dojo Toolkit的版本管理**:Dojo有多个版本,每个版本可能包含不同的修复和新特性,确保你使用的jar包与你的项目兼容至关重要。 10. **Integration with Java**:Dojo可以通过Java Servlets、JavaServer Pages...