ExtJS4.1 Data Package
来源:互联网 发布:增删算法统宗 编辑:程序博客网 时间:2024/05/07 07:01
数据(Data)
所谓数据包,它是用来装载和保存程序中的数据,并且组成41个类。其中 Model、Store和 Ext.data.proxy.Proxy是最重要的三个;它们几乎会在每一个应用中都被应用到,并且被一系列的卫星类(satellite classes)支持:
模型(Models)和存储(Stores)
数据包的核心就是 Ext.data.Model。Model用来表示程序中的数据类型,例如:一个电子商务系统会有Users模型、Products模型和Orders模型等。简单来说,模型(Model)就是一系列字段和字段值的集合。我们来看看比较重要的四种模型 — Fields、Proxies、 Associations 和Validations。
来看一下如何创建一个新的Model:
Ext.define('User', { extend: 'Ext.data.Model', fields: [ { name: 'id', type: 'int' }, { name: 'name', type: 'string' } ]});
Model通常结合Store一起使用,总体来说,Store就是一系列实例Model的集合。建立一个Store并且加载数据都比较简单:
Ext.create('Ext.data.Store', { model: 'User', proxy: { type: 'ajax', url : 'users.json', reader: 'json' }, autoLoad: true});
以上配置是通过Ajax代理(Ajax Proxy)来获取数据的,这里需要指定数据加载地址(url)和 Reader (用来解析数据)。本例中,由于服务器返回的是JSON,所以reader配置为“json”( Json Reader )来读取返回的数据。Store会自动从user.json这个地址加载数据,从user.json返回的JSON数据格式应该如下:
{ success: true, users: [ { id: 1, name: 'Ed' }, { id: 2, name: 'Tommy' } ]}
点击 Simple Store 亲手试一试。
内联数据(Inline data)
Store也可以加载内联数据。其实在本质上,Store是将我们传递给它的数据最终都转换成了Model实例:
Ext.create('Ext.data.Store', { model: 'User', data: [ { firstName: 'Ed', lastName: 'Spencer' }, { firstName: 'Tommy', lastName: 'Maintz' }, { firstName: 'Aaron', lastName: 'Conran' }, { firstName: 'Jamie', lastName: 'Avins' } ]});
亲手试一试
排序和分组(Sorting and Grouping)
Store可以在本地执行排序、过滤和分组操作,当然也支持远程的排序、过滤和分组:
Ext.create('Ext.data.Store', { model: 'User', sorters: ['name', 'id'], filters: { property: 'name', value : 'Ed' }, groupField: 'age', groupDir: 'DESC'});
在我们刚刚创建的store中,数据将会首先按照name进行排序,然后按照id进行排序;过滤器会将name值为Ed的User给过滤出来;然后数据还会按照age进行降序分组。详情请参见API文档
试一试
代理(Proxies)
Store通过代理(Proxy)来加载和保存数据模型。代理分为两种:客户端代理和服务端代理。像浏览器内存储和HTML本地化都是客户端代理的例子。服务端代理处理远程服务器的数据封装,例如:Ajax、JsonP和Reset。
代理可以直接定义在一个模型里面:
Ext.define('User', { extend: 'Ext.data.Model', fields: ['id', 'name', 'age', 'gender'], proxy: { type: 'rest', url : 'data/users', reader: { type: 'json', root: 'users' } }});// 使用用户模型代理Ext.create('Ext.data.Store', { model: 'User'});
这给我们带来了两点好处。首先,极有可能每个使用到user模型的Store都会以相同的方式来加载数据,这样就避免了为每个Store重复定义代理(Proxy)。其次,我们可以无需通过Store进行加载和保存数据。
// 获取一个User类的引用var User = Ext.ModelMgr.getModel('User');var ed = Ext.create('User', { name: 'Ed Spencer', age : 25});// 我们可以直接保存Ed,而不是必须首先将其添加到Store,这是由于我们配置了RestProxy,它会自动向/users这个地址发送POST请求ed.save({ success: function(ed) { console.log("Saved Ed! His ID is "+ ed.getId()); }});// 加载User 1并执行相关操作 (向 /users/1发起GET请求)User.load(1, { success: function(user) { console.log("Loaded user 1: " + user.get('name')); }});
Proxy也受益于HTML5的新功能- LocalStorage 和SessionStorage。尽管老版本的浏览器不支持HTML5的API,但它们确实是十分有用的,许多应用将极大的受益于他们。
尝试一下
关联(Associations)
多个Model可以通过Assocaition API联系在一起。绝大部门的应用都会处理许多不同的Model,而这些Model通常都是有联系的。例如一个博客应用程序中会有User、Post和Comment这些Model。用户可以发表文章,文章也会收到评论。我们可以向这样表示这些关系:
Ext.define('User', { extend: 'Ext.data.Model', fields: ['id', 'name'], proxy: { type: 'rest', url : 'data/users', reader: { type: 'json', root: 'users' } }, hasMany: 'Post' // shorthand for { model: 'Post', name: 'posts' }});Ext.define('Post', { extend: 'Ext.data.Model', fields: ['id', 'user_id', 'title', 'body'], proxy: { type: 'rest', url : 'data/posts', reader: { type: 'json', root: 'posts' } }, belongsTo: 'User', hasMany: { model: 'Comment', name: 'comments' }});Ext.define('Comment', { extend: 'Ext.data.Model', fields: ['id', 'post_id', 'name', 'message'], belongsTo: 'Post'});
可以很容易地表达您的应用程序中的不同Models之间的丰富关系。每个Model可以与其他Model有任意数量的关联(Associations),Model可以按照任何的顺序定义。一旦我们有一个Model的实例,我们可以很容易地遍历相关的数据 - 例如,如果我们想对指定用户的每篇文章的所有评论作记录,就可以这样做:
// Loads User with ID 1 and related posts and comments using User's ProxyUser.load(1, { success: function(user) { console.log("User: " + user.get('name')); user.posts().each(function(post) { console.log("Comments for post: " + post.get('title')); post.comments().each(function(comment) { console.log(comment.get('message')); }); }); }});
在我们上面创建的每一个hasMany关联都会产生一个新的函数添加到Model中。我们定义User model hasMany Posts,会新增user.posts()函数供我们在上面的代码片段使用。调用guser.posts()返回Post model的 Store配置。反过来,Post model获取comments() 函数是因为我们设置的Comments的hasMany关联。
关联不仅仅用于加载数据 – 创建新纪录的时候也非常有用:
user.posts().add({ title: 'Ext JS 4.0 MVC Architecture', body: 'It\'s a great Idea to structure your Ext JS Applications using the built in MVC Architecture...'});user.posts().sync();
在这里,我们实例化一个新的Post(文章),user_id字段会自动填充上用户ID。调用sync()通过其配置的Proxy保存新Post - 这又是一个异步操作。如果你想操作完成时发送通知,也可以添加一个回调函数(callback)。
belongsTo关联也可以生成新的Model方法,可以这样使用这些方法:
// get the user reference from the post's belongsTo associationpost.getUser(function(user) { console.log('Just got the user reference from the post: ' + user.get('name'))});// try to change the post's userpost.setUser(100, { callback: function(product, operation) { if (operation.wasSuccessful()) { console.log('Post\'s user was updated'); } else { console.log('Post\'s user could not be updated'); } }});
再次,加载函数(getUser)是异步的,需要一个回调函数来获取用户实例。setUser方法只需更新foreign_key(这里是user_id)为100并保存Post model。通常情况下,无论成功与否,都可以在完成保存操作的时候触发回调函数
加载嵌套数据(Loading Nested Data)
你也许会奇怪,为什么我们发送一个成功函数到User.load的调用,但在访问用户的文章和评论时却没有这样做。这是因为上面的例子中假定,当我们提出请求获取一个用户,服务器返回的用户数据会嵌套所有的文章和评论。通过设立像上面那样的关联,框架可以自动解析出嵌套在单一请求中的数据。框架不是先获取用户数据,然后调用另一个请求获取文章数据,然后再发出更多的请求获取评论,而是在一个服务器响应里返回所有数据:
{ success: true, users: [ { id: 1, name: 'Ed', age: 25, gender: 'male', posts: [ { id : 12, title: 'All about data in Ext JS 4', body : 'One areas that has seen the most improvement...', comments: [ { id: 123, name: 'S Jobs', message: 'One more thing' } ] } ] } ]}
数据全部是框架自动分析的。可以很容易地配置Model的代理来加载任何地方的数据,用他们的Reader来处理几乎任何返回格式(的数据)。至于Ext JS3,整个框架的许多组件都用到了Model和Store,如Grids、Trees 和Forms。
尝试一下
当然,可以用非嵌套的方式来加载数据。如果你需要“延迟加载(只有被需要的时候才会加载)”,这就会有用了。我们来像以前那样加载User数据,但我们假设响应只包含User数据而没有任何关联的Post。然后,我们将在回调中添加一个调用user.posts().load()的方法,以获得相关的Post数据。
// Loads User with ID 1 User's ProxyUser.load(1, { success: function(user) { console.log("User: " + user.get('name')); // Loads posts for user 1 using Post's Proxy user.posts().load({ callback: function(posts, operation) { Ext.each(posts, function(post) { console.log("Comments for post: " + post.get('title')); post.comments().each(function(comment) { console.log(comment.get('message')); }); }); } }); }});
尝试一下
验证(Validations)
Ext JS 4的数据验证变得丰富了许多。为了证明这一点,我们要用上述关联的例子。首先,让我们为User模型添加一些验证(validations):
Ext.define('User', { extend: 'Ext.data.Model', fields: ..., validations: [ {type: 'presence', name: 'name'}, {type: 'length', name: 'name', min: 5}, {type: 'format', name: 'age', matcher: /\d+/}, {type: 'inclusion', name: 'gender', list: ['male', 'female']}, {type: 'exclusion', name: 'name', list: ['admin']} ], proxy: ...});
验证的定义与字段的定义遵循相同的格式。在每一种情况下,我们指定一个验证的字段和类型。此例中,我们希望name字段必须存在,并且长度至少为5;age字段是一个数字,gender(性别)字段要么是“male”要么是“female”,username可以是除了“admin”的任何东西。某些验证还会采取额外的可选配置 - 例如长度验证可以采取Min和Max属性,格式可以用正则表达式等等。Ext JS的内置验证总共有5个,添加自定义的规则也很容易。首先,让我们看看内置验证:
- presence 确保该字段有一个值。计数0有效,但是空字符串无效。
- length 确保一个字符串在最小(min)和最大(max)长度之间。这两种约束(min和max)是可选的.
- format 确保一个字符串匹配一个正则表达式格式。在上面的例子中,我们确保年龄字段是由数字组成的。
- inclusion 确保值是特定的值(例如确保性别是男性或女性)。
- exclusion 确保不是某值(例如列入黑名单的username,像是“admin”)。
到目前位置,我们已经掌握了不同验证的用处,让我们尝试在用户实例中使用它们。我们将创建一个用户,并针对它运行验证,并指出任何错误:
// now lets try to create a new user with as many validation errors as we canvar newUser = Ext.create('User', { name: 'admin', age: 'twenty-nine', gender: 'not a valid gender'});// run some validation on the new user we just createdvar errors = newUser.validate();console.log('Is User valid?', errors.isValid()); //returns 'false' as there were validation errorsconsole.log('All Errors:', errors.items); //returns the array of all errors found on this model instanceconsole.log('Age Errors:', errors.getByField('age')); //returns the errors for the age field
这里的主要是validate()方法,它运行所有配置过的验证,并返回一个错误对象(Errors object)。这个简单的对象仅仅是一个被我们发现的所有错误的集合,还有一些方便的方法:比如isValid(),如果任何字段都没有错误就返回true; getByField(),它返回一个给定字段中的所有错误。
尝试一下
- ExtJS4.1 Data Package
- Extjs4.0数据包(Ext.data.package)以及数据模型(Ext.data.model介绍)详解
- EXTJS4 Ext.data.TreeStore model
- Ext JS Data Package
- ExtJS4学习笔记(十五)---Ext.data.Model
- EXTJS4 新特性之Ext.data.Model
- EXTJS4 新特性之Ext.data.Model
- Imputing missing data with R; MICE package
- Data.Table若干高级技巧【R package】
- Oracle Data Integrator 12c----包(Package)
- android asset到/data/data/PACKAGE/files的文件夹拷贝
- CNN代码分析之data package及 data provider
- android asset到/data/data/PACKAGE/files的文件夹拷贝
- extjs4.1 grid panel
- Extjs4.1 环境搭建
- Extjs4.1MVC详解
- ExtJs4.1布局详解
- Hello ExtJs4.1
- 1001 hibernate
- 总结一下在学习WebService中学习遇到的一些不懂的概念
- How to fix “Firefox is already running” error by Matt Cutts on January 2, 2007 in How to,Linux/Ubu
- 字符串匹配
- ActionContext与ServletActionContext区别
- ExtJS4.1 Data Package
- greenplum 常用SQL(不断更新)
- 判断某一年是否为闰年
- JSP中getParameter getAttribute 区别 详解
- Gforge5 使用过程中的FAQ
- 查询优化心得
- 循环判断中的对话框
- VMware中去掉Linux报警声
- 大数运算