ExtJs数据代理我们介绍常用的四种,但会着重介绍ajax代理,因为日常开发中,这个最为常用
Ext.data.proxy.Ajax
AjaxProxyAjax数据代理类)是你的应用程序中使用最广泛的获取数据的方式. 它使用AJAX请求来从服务器获取数据, 然后通常将它们放入 Store中.
让我们来看一个典型的配置. 这里我们为一个Store设置一个AjaxProxy代理. 首先我们准备好一个 Model:
Ext.define'User', { extend: 'Ext.data.Model', fields: ['id', 'name', 'email'] }); //一个包含AjaxProxy代理的Store, 使用参数方式绑定. var store = Ext.create'Ext.data.Store', { model: 'User', proxy: { type: 'ajax', url : 'users.json' } }); store.load); store.on'load',functionstore,records){ store.eachfunctionrecord){ console.logrecord.get'name')); }); })
这里说明下官网的例子是直接使用store.each 方法 ,但那是没用的
store 中each)方法的使用应在load完使用,确切的说应该在on’load’)事件中使用,切记
我们的例子将会把user数据加载到Store中, 首先我们定义一个Model,
Model包含的字段fields)即为从服务器返回 数据的相应字段. 接下来我们定义一个Store, 它包含了一个proxy配置项.
此配置项将会自动转换为一个 Ext.data.proxy.Ajax类的实例, 此实例包含了我们定义的url参数. 这等效于下面这段代码
new Ext.data.proxy.Ajax{ url: 'users.json', model: 'User', reader: 'json' });
这里出现了两个额外的参数 – model和reader.
这些参数在通过Store来创建proxy实例时是默认指定的 – Store中已经定义了 Model,并且Proxy的默认Reader为JsonReader.
最后我们调用store.load), 触发执行AjaxProxy的action, 向配置的url发送请求本示例为’users.json’). 由于我们执行的是数据读取, 所以讲发送一个GET方式的请求.请求方式的定义参见actionMethods – 默认所有读数据请求(read)的方式为GET, 而所有写请求(create、update、destroy)的方式为POST)
配置项
actionMethods: { create : 'POST', read : 'GET', update : 'POST', destroy: 'POST' }
限制
AjaxProxy无法跨域获取数据. 例如你的程序地址为http://domainA.com, 那么你就无法从http://domainB.com获取数据. 这是因为浏览器都有 一个内置的安全机制来阻止AJAX的跨域请求.
如果你需求从其他域名地址获取数据, 并且你无法从服务器端设置代理某些运行在你自己服务器端的程序, 用来将请求转发给http://domainB.com, 但客户端看来数据还是来自http://domainA.com), 你可以使用Ext.data.proxy.JsonP代理和JSON-P技术, 这样只要http://domainB.com 上的服务器支持JSON-P响应, 就能够解决你的跨域请求问题.
配置Reader和Writer
AjaxProxy可以配置任意类型的Reader来解读服务器端的响应. 如果不显式指定Reader, 将默认使用 JsonReader. 可以使用简单属性对象的方式来配置Reader, 代理将自动将其转换为Reader类的实例:
var proxy = new Ext.data.proxy.Ajax{ model: 'User', reader: { type: 'xml', root: 'users' } }); proxy.getReader); //返回一个XmlReader的实例.
生成Url
AjaxProxy会自动将排序,过滤,翻页和分组参数添加到生成的url中. 可以使用下面这些属性来配置这些参数:
pageParam –
控制如何向服务器发送页数同样参见startParam和limitParam)sortParam –
控制如何向服务器发送排序信息groupParam –
控制如何向服务器发送分组信息filterParam –
控制如何向服务器发送过滤信息
每个AjaxProxy发出的请求对象由一个Operation对象来描述. 为了说明我们是如何生成自定义url的, 让我们 看看下面这个Operation:
var operation = new Ext.data.Operation{ action: 'read', page : 2 });
然后我们用此Operation来发布请求, 通过调用read:
var proxy = new Ext.data.proxy.Ajax{ url: '/users' }); proxy.readoperation); //GET /users?page=2
很简单吧 – Proxy代理类只需要复制Operation中的page值即可. 我们还能自定义如何向服务器发送page数据:
var proxy = new Ext.data.proxy.Ajax{ url: '/users', pageParam: 'pageNumber', //默认page }); proxy.readoperation); //GET /users?pageNumber=2
还有另一个方案, 可以配置Operation来发送start和limit参数代替page:
var operation = new Ext.data.Operation{ action: 'read', start : 50, limit : 25 }); var proxy = new Ext.data.proxy.Ajax{ url: '/users' }); proxy.readoperation); //GET /users?start=50&limit;=25
同样地我们可以自定义startParam limitParam
var proxy = new Ext.data.proxy.Ajax{ url: '/users', startParam: 'startIndex',//默认start limitParam: 'pageSize'//默认limit }); proxy.readoperation); //GET /users?startIndex=50&pageSize;=25
AjaxProxy还会向服务器发送排序和过滤信息. 让我们来看看如何使用Operation来表示:
var operation = new Ext.data.Operation{ action: 'read', sorters: [ new Ext.util.Sorter{ property : 'name', direction: 'ASC' }), new Ext.util.Sorter{ property : 'age', direction: 'DESC' }) ], filters: [ new Ext.util.Filter{ property: 'eyeColor', value : 'brown' }) ] });
当使用一个包含sorters和filters参数的Store来加载数据时,
就会在内部生成上面这样的对象. 默认情况下, AjaxProxy 会对sorters和filters进行JSON转换, 从而得到如下结果注意url发送前会被加密, 这里为便于阅读使用未加密的串):
var proxy = new Ext.data.proxy.Ajax{ url: '/users' }); proxy.readoperation); //GET /users?sort=[{"property":"name","direction":"ASC"},{"property":"age","direction":"DESC"}]&filter;=[{"property":"eyeColor","value":"brown"}]
同样地我们能够自定义这些参数项. 假设我们的服务器读取排序信息的格式是”sortBy=name#ASC,age#DESC”. 我们可以像这样配置AjaxProxy来提供这种格式:
var proxy = new Ext.data.proxy.Ajax{ url: '/users', sortParam: 'sortBy', filterParam: 'filterBy', //我们自定义实现排序信息转码方法 - 将sorters转换为"name#ASC,age#DESC" encodeSorters: functionsorters) { var length = sorters.length, sortStrs = [], sorter, i; for i = 0; i < length; i++) { sorter = sorters[i]; sortStrs[i] = sorter.property + '#' + sorter.direction } return sortStrs.join","); } }); proxy.readoperation); //GET /users?sortBy=name#ASC,age#DESC&filterBy;=[{"property":"eyeColor","value":"brown"}]
同样我们还能够通过自定义实现encodeFilters方法来对filters信息进行转码
Ext.data.proxy.JsonP
JsonP代理用在当你想从你自己的应用服务器以外的域名加载数据时跨域调用). 比如你的应用运行在http://domainA.com上, 那么就无法通过 Ajax从http://domainB.com加载数据,
因为浏览器不允许跨域的ajax请求.
而通过JsonP代理我们可以摆脱这个限制. 每当进行AJAX请求时, JsonP代理就在DOM中注入一个<script>
标签. 比如我们想从http://domainB.com/users 这个url下加载数据,
那么就会注入一个如下的script标签:
<script src="http://domainB.com/users?callback=someCallback"></script>
在我们注入了上面这个标签后, 浏览器就会向这个url发送一个请求. 通过url中的callback, 我们通知domainB的服务器: 当结果返回时请调用 此回调函数并传入返回的数据. 只要服务器将响应结果组成如下格式,
调用就成功了:
Ext.regModel"User",{ fields:[ {name:'name',type:'string'} ], proxy:{ type:'jsonp',//跨域交互的代理 url:'http://www.uspcat.com/extjs/person.php' } }); var person = Ext.ModelManager.getModel'User'); person.load1,{ scope:this, success:functionmodel){ alertmodel.get'name')); } });
Ext.data.proxy.LocalStorage
LocalStorageProxy使用最新的HTML5本地数据库API, 将Model数据保存在本地客户端. HTML5本地数据库是一个
键值对存储例如 不能存储像JSON这样的复杂对象), 因此LocalStorageProxy在保存和读取数据时, 自动进行序列化和反序列化.
本地数据库在保存用户个人信息时非常有用, 从而不再需要在服务端建立数据结构.
Ext.define'User', { fields: ['id', 'name'], extend: 'Ext.data.Model', proxy: { type: 'localstorage' } });
var store = new Ext.data.Store{ model:'User' }); store.add{name:'somnus'}); // 保存数据 store.sync); // 读取数据 store.load); store.eachfunctionrecord){ console.inforecord.get'name')); });
Ext.data.proxy.Memory
内存代理. 此代理使用简单的本地变量进行数据的存储/读取, 所以其内容将在每次页面刷新时被清除.
通常此代理并不直接使用, 而是作为Store的辅助服务对象, 为其在加载数据时提供reader对象. 例如, 假设我们有一个 User Model和Store, 以及一些我们想要加载的内部数据, 但是这些数据的格式并不是很合适: 这时我们就可以用一个带有JsonReader的MemoryProxy 来为Store读取这些数据:
//我们将在store中使用的model对象 Ext.define'User', { extend: 'Ext.data.Model', fields: [ {name: 'id', type: 'int'}, {name: 'name', type: 'string'}, {name: 'phone', type: 'string', mapping: 'phoneNumber'} ] }); //数据字段不是按照model中定义排列的 - 字段'phone'在此称为'phoneNumber' var data = { users: [ { id: 1, name: 'Ed Spencer', phoneNumber: '555 1234' }, { id: 2, name: 'Abe Elias', phoneNumber: '666 1234' } ] }; //请注意我们是如何通过设置reader的'root'来满足上面的数据结构的. var store = Ext.create'Ext.data.Store', { autoLoad: true, model: 'User', data : data, proxy: { type: 'memory', reader: { type: 'json', root: 'users' } } });
var memoryProxy = Ext.create"Ext.data.proxy.Memory",{ data:data, model:'User' }) data.push{name:'sunday',age:1}); memoryProxy.update new Ext.data.Operation { action:'update', data:data }), functionresult){}, this ); memoryProxy.read new Ext.data.Operation), functionresult){ var datas = result.resultSet.records; Ext.eachdatas,functionmodel){ console.infomodel.get'name')); }); var totalRecords = result.resultSet.total; alert'读取内存数据,记录总是:' + totalRecords); } );