预览ExtJS 4.0的新功能(五):焕然一新的Store/Proxy

接上文

Proxy

Ext.data.Proxy 是一个十分关键的数据通讯类。Proxy 直译“代理”,可数据怎么能够代理?有点不通!Proxy 到底指的是什么意思呢?

依小弟浅见,定义 Proxy 就是定义数据源,至少 Ext 中 AjaxProxy/ScriptProxy/LocalProxy/SessionProxy 表现如此。当 Store 要为Ext.data.Model4 加载或者保存数据的时候,必须通过这个 Proxy 类。具体说,Proxy的操作就是将所有最终的数据操作视作为增、删、改、查四种,即Create、Read、Update或Delete。这四个操作分别映射了create(), read(), update() 和destroy()。不同的Proxy子类的任务就是要逐个去具体化这些CRUD是什么了,然后才返回到Store。而CRUD方法中,都期待一个Ext.data.Operation 对象的独占参数传入。……Operation 是什么?Opeartion 是4.0的新内容,封装了 Stroe 将要执行的动作信息、要修改的Ext.data.Model 实例等等。 在完成阶段,每个 CRUD 方法皆支持异步的回调函数。

API的实现中,Proxy可分为ServerProxy和ClientProxy两大类:

预览ExtJS 4.0的新功能(五):焕然一新的Store/Proxy_第1张图片

Server Proxy就是通过Request发送数据到远端;Client Proxy的意思是在客户端保存本地的数据。下面就展开作介绍。

Ext.data.ServerProxy(AjaxProxy)

ServerProxy是AjaxProxy和ScriptTagProxy这个两个类的超类。一般来说AjaxProxy是典型情况下最常用的Proxy,页面代码中设定参数,经过AJAX管道从服务端取得数据。AjaxProxy只针对同源的页面。不能脱离本页面的范围进行跨域(CrossDomain)获取数据。要进行跨域获取数据则使用ScriptTagProxy。理想情况下,应该称ServerProxy为HttpProxy,因为这是涵盖所有HTTPProxy的超类——但在Ext4.0中作了调整,HttpProxy则矮化到只是AjaxProxy的简写。原本3.x中的HttpProxy到这里却变为ServerProxy。

预览ExtJS 4.0的新功能(五):焕然一新的Store/Proxy_第2张图片

ScriptProxy的差别与旧版不大,原理上也是采用script tag进行变相的跨域,缺点是只适合JSON数据格式的时候。关于跨越的方案,我们还可以多看看Ext.util.JSONP这个类。

Ext中如何REST式Web资源?

如果需要进行RESTful的风格应用,我们可以在AjaxProxy的“GET/POST”基础上增加“PUT/DELETE”,充分利用这四个HTTP动词,对此,Ext的实现就是Ext.data.ResetProxy。ResetProxy中所提供的'create','read','update' and'destroy'分别对应着POST、GET、PUT、DELETE方法(注意此处与AjaxProxy.actionMethods的不同,AjaxProxy.actionMethods限定在GET/POST操作内完成。)。也就是说,ResetProxy管理着数据的API,除了创、见、变、灭的这四种CRUD操作进行了定义之外,还分别将这些操作映射到了RESTful的HTTP方法:GET、POST、PUT和DELETE。

其中Ext.data.RestProxy.actionMethods一项应保持不变除非使用全局Ext.override()的方法覆盖默认值,另外也可以用重写getMethod(由Ext.data.AjaxProxy继承得到)来代替。总之,我们还可以扩展其他的HTTP动词。鉴于RestProxy代码行数比较少,特贴出如下:

/** * @author Ed Spencer * @class Ext.data.RestProxy * @extends Ext.data.AjaxProxy */ Ext.data.RestProxy = Ext.extend(Ext.data.AjaxProxy, { actionMethods: { create : 'POST', read : 'GET', update : 'PUT', destroy: 'DELETE' }, api: { create : 'create', read : 'read', update : 'update', destroy: 'destroy' } });

与旧版3.3的Ext.data.Api比较(参见3.x的介绍),虽然都是围绕REST而设,但新版ResetProxy代码行数大幅减少,之所以这样,初步判断是合理地发挥了OO方法论所带来的结果(对比一下旧版Api是单例的设计)。

Ext.data.ClientProxy(MemoryProxy/WebStorageProxy)

Ext.data.ClientProxy是为客户端而设的存储基类(因为ClientProxy是基类,请不要直接使用)。它的子类有Ext.data.MemoryProxy和Ext.data.WebStorageProxy,这两个子类的主要用途如下:

  • MemoryProxy是内存中proxy,所以一刷新浏览器的话,就没有了本地数据。也就是MemoryProxy内的都是指内存中的数据,一旦刷新页面数据将不复存在。通常来说不会直接使用到这个类,什么时候使用呢?比如一个User模型和来源不同的数据,它们之间的结构不是十分吻合,我们便可以灵活使用MemoryProxy和JsonReader作转换,然后加载到Store中去。
  • WebStorageProxy是Ext.data.LocalStorageProxy及Ext.data.SessionStorageProxy 的基类,它使用了HTML5新型的ley/value客户端存储方案来保存Ext.data.Model实例,达到离线持久化之目的。实例化WebStorageProxy的过程中,如果浏览器不支持HTML5客户端存储方案,就立刻抛出一个异常。

预览ExtJS 4.0的新功能(五):焕然一新的Store/Proxy_第3张图片

如UML图所示,WebStorageProxy有标准的CRUD方法;MemoryProxy只有read()方法;但它们都有clear()方法,这个方法会删除掉客户端的使所有记录数据,包括像IDs的这样的支持数据。下面是利用Memory作转换的一个例子:

Edit 2011-9-22 示例代码可能与最新版本的 Ext Model 有区别,但不影响主干意思——感谢 Thanks to QiuQiu/太阳。

// 这时Store中所使用的模型。 Ext.regModel('User', { fields: [ {name: 'id', type: 'int'}, {name: 'name', type: 'string'}, {name: 'phone', type: 'string', mapping: 'phoneNumber'} ] }); // 此数据并不是与我们上面定义的模型所吻合,就是phone字段必须映射为phoneNumber。 var data = { users: [ { id: 1, name: 'Ed Spencer', phoneNumber: '555 1234' }, { id: 2, name: 'Abe Elias', phoneNumber: '666 1234' } ] }; // 注意如何设置reader中的“root: 'users'”,看看是怎么对应上面的数据结构的。 var store = new Ext.data.Store({ autoLoad: true, model: 'User', data : data, proxy: { type: 'memory', reader: { type: 'json', root: 'users' } } });

前提提到,WebStorageProxy 有两个子类,它们是:

  • LocalStorageProxy:以 HTML5 本地存储为服务对象。
  • SessionStorageProxy:以 HTML5 Session 存储为服务对象。

再次强调,无论 LocalStorageProxy 还是 SessionStorageProxy 都是涉及新型的 HTML5 功能的,所以假设浏览器不支持 HTML5 的功能,WebStorageProxy 的构造函数立刻就会抛出一个异常。使用本地存储的时候,需要一个独一无二的 ID 作为存放全部记录对象的 KEY,并且切记送入的 ID 必须是独一无二的,否则调用过程将是不稳定的。如果没有送入 ID,则 storeId 会视为 ID。如果什么 ID 都没有将会抛出一个异常。

Proxy 总是结合 Ext.data.Store 使用的,另外你也可以直接地创建 Proxy 的,如下两例:

new Ext.data.Store({ proxy: { type: 'localstorage', id : 'myProxyKey' } }); // 直接创建 new Ext.data.LocalStorageProxy({ id : 'myOtherProxyKey' });

新提供的 WebStorageProxy 包括了离线(offline)的任务,除了 WebStorageProxy,4.0的 Ext 还提供 WebSqlProxy 使得存储客户端可以借助 SQL 语句来完成。不过现在没有发现 WebSqlProxy 的源码,估计到最终发布才会看见了。

预览ExtJS 4.0的新功能(五):焕然一新的Store/Proxy_第4张图片

Store/Proxy小结

预览ExtJS 4.0的新功能(五):焕然一新的Store/Proxy_第5张图片

Data 变化很大,可列举很多的陈述,这儿提出一个小地方:新的 Ext.data.TreeStore/Ext.data.TreeReader 引入。Ext.Tree不再使用TreeLoader的绑定数据形式,那是旧3.x之前的形式。其实没有必要为Tree组件单独而设一种不同的数据模型。Ext4 意识到这点,在这次发布中就可以看到Tree统一归Store的数据源。

如此这类的还有其他的吧~

话说核心团队成员EdSpencer是ExtJS4的架构设计者,他在SenchaCon大会上负责Ext的架构、新特性的演讲,另外Ext.data.*即就是出自他手的。借此处说话的机会,我觉得应该客气地多谢他,不管怎么人家也是开源的。我们看到的是Ext.data.*得到了重新编写,形成这样的API局面,个人认为这是4.0其中变化最大的一项,并且是迷人的地方。诚如官方RoadMap所说的“A rewrite of the Ext.datapackage with a brand new architecture and enormous newcapabilities”果然名不虚传。

Data部分还有戏。Ext.data.Operation实际上说的是CRUD操作,也就是介乎于Store与Proxy之间的CRUD操作。而Ext.data.Batch是Opeartion的集合形式,把多个Operation打包起来就成为了Batch。另外还有reader/writer,下一期有机会再展开讨论。

转载请注明出处Ext中文网 (http://www.ajaxjs.com)。

你可能感兴趣的:(html5,ext,delete,存储,ExtJs,autoload)