本文已添加至Sencha Touch 2快速入门系列索引:http://blog.csdn.net/ardy_c/article/details/7544470
转载请注明出处:http://blog.csdn.net/ardy_c/article/details/7631641
在开发一个应用的时候,很多情况下前端页面需要与后台进行数据交互,包括数据的读取和持久化。Sencha Touch 2 为我们提供了一个data package来实现数据交互的功能。而这个data package的运作,是通过以下三个模块相互支撑的:Model、Store、Proxy。
Model
Model(Ext.data.Model),就是一个数据模型。它所表现的就是你的应用所关心的一个数据实体模型。说白一些,就是你的应用所需要的数据实体包含哪些字段,每个字段是什么类型。Model 就是负责诠释这些东西,是一个字段信息的集。当然,它的功能不止这些,后面我们会详细介绍。先看看以下一段示例代码:
Ext.define('User', { extend: 'Ext.data.Model', config: { fields: [ { name: 'id', type: 'int' }, { name: 'name', type: 'string' } ] } });以上代码,通过扩展Model定义了一个叫User的Model。通过向config属性传入名叫fields的数据对象,设置好当该model实例化时,自动定义model的fields属性。而fields属性的作用,就是定议该model含有哪些字段,分别是什么类型的。
Store
Store(Ext.data.Store),如果model是字段的集合,那些Store正好与之相对应,是数据记录的集合,每条记录都存在着与model相对应的字段值。另外,它还能对数据进行排序、过滤、组合等操作。
Ext.create('Ext.data.Store', { model: 'User', data: [ { id: 1, name: 'Ed' }, { id: 2, name: 'Tommy' } ]});在上面代码中,我们创建了一个Store。由此看出,Store是基于Model的记录集合。data属性内是一个对象数组。每个对象数组元素正是一条记录。每个元素中,各个属性正好与User Model定义的属性相对应。
Proxy
Proxy,一般为Store所用,用于处理数据的加载和持久化。其中,Proxy有两种类型:客户端和服务端。客户端是指基于浏览器内存的数据读取和存储,或者当HTML5的Local Storage属性可用时,我们可以进行基本客户端本地的数据读取和存储;服务端,相信大家也比较熟悉,包含有Ajax、JsonP和Rest。我们来看看一个Proxy的使用实例:
Ext.define('User', { extend: 'Ext.data.Model', config: { fields: ['id', 'name', 'age', 'gender'], proxy: { type: 'rest', url : 'data/users', reader: { type: 'json', root: 'users' } } } }); // 使用model中定义的proxy Ext.create('Ext.data.Store', { model: 'User' });
Proxy一般为Store所用,但也可以在Model中进行定义。当Proxy定义于Model中,在创建Store的时候,store自动与在model中定义的proxy进行关联。在Model上定义Proxy有两个好处:1,Model可能会被多个Store引用到,在Model上定义了Proxy,就不用在Store上重复定义了;2,可能绕开Store,直接在Model上加载和存储数据。在上面代码建立了一个rest方式的proxy(type: 'rest')。url是rest资源的地址。由于请求响应返回的时json格式结果,所以我们设定了一个json reader去对结果进行解析,以结果中的users结果作为根开始读取响应信息。我们再来看一个例子:
var User = Ext.ModelMgr.getModel('User'); var ed = Ext.create('User', { name: 'Ed Spencer', age : 25 }); ed.save({ success: function(ed) { console.log("Saved Ed! His ID is "+ ed.getId()); } }); User.load(1, { success: function(user) { console.log("Loaded user 1: " + user.get('name')); } });以上代码需要与上一段代码一起使用。通过Model存取数据,无需建立store。当ed调用save方法时,会通过之前设置好的rest代理post到data/users中去进行处理;而调用load方法时,会通过rest代理通过get方法向data/users/1 请求User 1的数据。
验证(Validation)
在日常的表单处理中,数值的验证是非常频繁使用的操作。Sencha Touch 2 为大家提供了一些方便的验证方法,只需要在Model中加入一些验证逻辑,即可实现对输入数据的验证。我们来看看一面一段代码:
Ext.define('User', { extend: 'Ext.data.Model', config: { fields: ..., validations: [ { type: 'presence', field: 'name' }, { type: 'length', field: 'name', min: 5 }, { type: 'format', field: 'age', matcher: /\d+/ }, { type: 'inclusion', field: 'gender', list: ['male', 'female'] }, { type: 'exclusion', field: 'name', list: ['admin'] } ], proxy: ... } });以上代码是在Model中加入了一个validations的属性,值是一个数据对象的数组。每一个数据对象里的数据用于配置某一字段的验证逻辑。其中,field是指关联哪个字段,type是指使用哪种验证逻辑。每个字段可以绑定多种验证逻辑,例如上面代码name字段就绑定了presence、length和exclusion三种方式。具体这些是代表怎样的逻辑,下面给大家介绍一下:
现在我们来验证一下上面的代码所添加的验证功能是否可以正常工作。
// 新建一个User实例,我们特意违返验证规则 var newUser = Ext.create('User', { name: 'admin', age: 'twenty-nine', gender: 'not a valid gender' }); // 执行验证 var errors = newUser.validate(); console.log('Is User valid?', errors.isValid()); // 存在错误信息,返回 false console.log('All Errors:', errors.items); // 返回这个实例中产生的错误的数组 console.log('Age Errors:', errors.getByField('age')); // 返回该字段中产生的错误信息