ExtJS4 API文档阅读(四)——Data
2019独角兽企业重金招聘Python工程师标准>>>
ExtJS4 API文档阅读(四)——Data
数据
Data包负责加载和保存你应用程序中的所有数据,由41个类构成,其中有三个类是最重要的,分别是模型类(Model),存储类(Store),代理类(Ext.data.proxy.Proxy)。它们几乎在每个应用程序中都被使用到,并且有很多相附类为它们提供支持。
模型类和存储类
模型类(Ext.data.Model)是data包的核心部件。每个模型代表应用程序中的一些数据类型-例如一个电子商务应用程序可以有Users、Products、Orders等模型类。简单来说,模型仅仅是一些域和每个域对应数据的集合。我们将重点研究模型类中的四个主要部分—域(Fields)、代理(Proxies)、关联(Associations)和验证(Validations)。
现在让我们看看如何创建一个模型类:
Ext.define('User', {extend: 'Ext.data.Model',fields: [{ name: 'id', type: 'int' },{ name: 'name', type: 'string' }]
});
模型类通常在存储类中使用,这些存储类主要是一些模型实例的集合。设置存储类和加载它的数据是很简单的:
Ext.create('Ext.data.Store', {model: 'User',proxy: {type: 'ajax',url : 'users.json',reader: 'json'},autoLoad: true
});
我们用Ajax代理( Ajax Proxy)配置我们的存储类,告诉它加载数据的url地址和用来解码数据的读取器(Reader)。这样,我们的服务器将返回JSON格式的数据,我们可以使用设置的Json读取器(Json Reader)来解析响应。上面创建的存储类实例从url地址users.json中自动加载一系列User模型类实例的数据。
users.json应该返回如下所示的JSON字符串:
{success: true,users: [{ id: 1, name: 'Ed' },{ id: 2, name: 'Tommy' }]
}
请查看Simple Store获取一个演示实例。
内联数据
存储类实例也可以加载内联数据,它们转换每个传递进data中的对象为模型类实例:
Ext.create('Ext.data.Store', {model: 'User',data: [{ firstName: 'Ed', lastName: 'Spencer' },{ firstName: 'Tommy', lastName: 'Maintz' },{ firstName: 'Aaron', lastName: 'Conran' },{ firstName: 'Jamie', lastName: 'Avins' }]
});
内联数据的例子(Inline Data example)
排序和分组
存储类实例能在本地执行排序、过滤和分组,同样也提供远程排序、过滤和分组:
Ext.create('Ext.data.Store', {model: 'User',sorters: ['name', 'id'],filters: {property: 'name',value : 'Ed'},groupField: 'age',groupDir: 'DESC'
});
我们刚刚创建的存储类实例中,数据首先将按照name排序,其次按id排序;并且数据将被过滤为仅包含name为’Ed’的Users,然后数据将按年龄进行分组且遵循由小到大的顺序。任何时候调用存储类的API进行排序、过滤和分组都是是很轻松的。查看排序、分组、过滤存储类实例(Sorting Grouping Filtering Store)获取一个演示示例。
代理
代理类被存储类使用以便于管理加载和保存模型类数据。有两种类型的代理:客户端代理(Client)和服务器端代理(Server)。客户端代理包括存储数据在浏览器内存的内存方式(Memory)和使用HTML5本地存储器(可用时)的本地存储方式(Local Storage)。服务器端代理操作一些从远程服务器调度来的数据,例如包括Ajax,Jsonp和Rest方式。
代理方式可以直接在模型类中定义,如下:
Ext.define('User', {extend: 'Ext.data.Model',fields: ['id', 'name', 'age', 'gender'],proxy: {type: 'rest',url : 'data/users',reader: {type: 'json',root: 'users'}}
});// Uses the User Model's Proxy
Ext.create('Ext.data.Store', {model: 'User'
});
这对我们有两方面的好处:首先,使得每个使用User模型类的存储类实例以相同方式加载数据变得可行,这样我们避免了必须为每个存储类实例复制相同代理方式的定义。其次,现在我们可以不必使用存储类来加载和保存模型数据:
// Gives us a reference to the User class
// 创建一个User类的引用
var User = Ext.ModelMgr.getModel('User');
var ed = Ext.create('User', {name: 'Ed Spencer',age : 25
});
// We can save Ed directly without having to add him to a Store first because we
//我们可以直接保存ed而不用先把它添加到一个存储类中,因为我们配置了
// configured a RestProxy this will automatically send a POST request to the url /users
//一个能自动发送一个POST请求到指定url的Rest代理
ed.save({success: function(ed) {console.log("Saved Ed! His ID is "+ ed.getId());}
});// Load User 1 and do something with it (performs a GET request to /users/1)
//加载User 1并对其一些相关操作(执行一个GET请求到 /users/1)
User.load(1, {success: function(user) {console.log("Loaded user 1: " + user.get('name'));}
});
也有利用HTML5新功能-- LocalStorage和 SessionStorage – 的代理模式。尽管旧的浏览器不支持这些新的HTML5 APIs,它们仍然是有用的,因为很多应用程序将从这些新特性的存在中受益。
直接在模型类中使用代理的例子(Example of a Model that uses a Proxy directly)
关联
模型类之间可以通过关联API链接在一起。大多数应用程序需要处理很多不同的模型类,并且这些模型类之间通常是相关联的。例如一个博客写作应用程序可能有User(用户)、Post(文章)、Comment(评论)等模型类。每个用户(User)可以创建多篇文章(Posts),并且每篇文章接受很多评论(Comments)。我们可以如下表示这些关系:
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'
});
这将使得在你的应用程序中表示这种复杂关系变得简单。 每个模型类可以和其他模型类有任意多的关联,并且你的模型类可以按任意顺序定义。一旦我们创建了一个模型类实例,我们可以很轻松地遍历与其相关联的数据 -- 例如,如果我们想记录一个给定用户的每篇文章的所有相关评论,我们可以如下这样操作:
// Loads User with ID 1 and related posts and comments using User's Proxy
//加载User使用ID 1和相关的文章和评论使用User的代理
User.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关联将产生一个新方法添加到这个模型类上。我们声明的每个User模型类实例有许多(hasMany)文章(Posts),这将为我们添加user.posts()方法,如上面代码段中使用的那样。调用user.posts()方法将返回一个配置了Post模型的存储类实例。依次类推,Post模型实例获取了一个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赋值给Post中的user_id字段。调用sync()方法,将通过配置的代理方式来保存新创建的Post模型类实例 – 再者,如果你想让操作完成时得到反馈,你可以调用异步操作并传递进一个回调函数来实现。属于(belongsTo)关联也能在模型类实例中生成一个新方法,如我们下面介绍的这个示例:
// get the user reference from the post's belongsTo association
//得到user实例引用从post实例的belongsTo关联配置
post.getUser(function(user) {console.log('Just got the user reference from the post: ' + user.get('name'))
});
// try to change the post's user
//尝试改变文章的user
post.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)是异步调用的,并且需要一个回调函数作为参数来获得user实例。setUser方法仅更新外键(本例中的user_id字段)的值为100,并保存这个Post模型类实例。通常,不管成功与否,当保存操作完成时,传递进去的回调函数都将被触发。
加载内嵌的数据
你或许想知道为什么调用User.load方法时,我们传递一个success方法,但当访问User的文章(Post)及评论(Comment)时我们并不需要这样做。这是因为上面的例子中,我们假定当发送请求以获取一个用户的信息时,服务器返回了该用户的数据及所有嵌套的文章和评论的数据。上例我们通过设置关联配置,框架在一次请求中就能自动解析出嵌套的数据。不是靠先发送一个请求获取用户数据,另一个请求获取文章数据,再发送其他请求以获取每篇文章的评论数据这种模式,我们可以在一次服务器响应中返回所有的数据,如下:
{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'}]}]}]
}
这些数据将被框架自动解析出来。配置模型类的代理方式以用来加载任何地方的数据会变得很轻松,并且它们的阅读器模式几乎可以处理任何格式的响应数据。和Ext JS 3一样,模型类和存储类在整个框架中被许多组件使用,例如表格,树,表单。
查看关联和验证(Associations and Validations)的演示示例以获取一个可实际操作并且具有关联关系的模型实例。
当然,你可以以一种非嵌套的方式加载你的数据。如果你仅想需要时加载相关的数据,这种“懒惰加载”模式将可能是有效地。如前所做,我们仅加载User数据,除此之外,我们假定返回的响应仅包含User数据,没有任何相关联的文章(Post)数据。然后,我们在user.posts().load()方法添加回调函数中以获取相关的文章(Post)数据:
// Loads User with ID 1 User's Proxy
User.load(1, {success: function(user) {console.log("User: " + user.get('name'));// Loads posts for user 1 using Post's Proxyuser.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'));});});}});}
});
查看懒惰关联(Lazy Associations)模式可以获取一个完整的示例
验证
自Ext JS 4起,模型类由于提供了验证数据的功能而变得更加丰富精彩了。为了证明这点,我们将在前面使用过的关联例子的基础上构建一个示例。首先让我们添加一些验证到User模型类中:
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,并且用户名可以为除了admin外的其他任何名称。一些验证器可能具有其他的可选配置 -- 例如,长度验证可以具有最大和最小属性,格式(format)可以具有匹配(matcher)属性等。Ext JS有五种内置的验证器,且可以轻松地添加用户自定义规则。首先让我们看看这五种类型:
- 存在(presence) 确保该域必须有确定值。0被看作有效值,但空字符串将不被视为有效值。
- 长度(length) 确保一个字符串长度位于最大和最小值之间。两个参数都是可选的。
- 格式(format) 确保一个字符串匹配指定的正则表达式。上例中我们确保age域必须为数字。
- 包含(inclusion) 确保该域的值在指定的数值集合中(例如确保性别只能是男或女)。
- 排除(exclusion) 确保该域的值不在指定的数值集合中(例如用户名不能为admin)
既然我们已经理解了不同验证器的功能,让我们尝试在一个User实例中使用它们。
我们创建一个user实例并在其中运行验证器,注意产生的任何错误:
// now lets try to create a new user with as many validation errors as we can
// 现在让我们尝试创建一个user实例,并产生尽量多的验证错误
var newUser = Ext.create('User', {name: 'admin',age: 'twenty-nine',gender: 'not a valid gender'
});
// run some validation on the new user we just created
// 在我们刚刚创建的user实例中运行一些验证器
var errors = newUser.validate();
console.log('Is User valid?', errors.isValid()); //returns 'false' as there were validation errors 当有验证器错误产生时,返回false
console.log('All Errors:', errors.items); //returns the array of all errors found on this model instance返回该模型类实例所有错误组合成的数组
console.log('Age Errors:', errors.getByField('age')); //returns the errors for the age field返回age域产生的错误
这里的关键函数是validate(),该函数运行所有配置验证器并返回一个Errors对象。这个简单的对象为所有错误的集合,并且添加了一些便利的方法,例如isValid() -- 当任何域都没有错误产生时,返回true,还有getByField()方法,返回给定域产生的所有错误。
请查看关联和验证(Associations and Validations)示例以获取一个使用验证器的复杂例子。
转载于:https://my.oschina.net/yoyoko/blog/130966
ExtJS4 API文档阅读(四)——Data相关推荐
- 聚合API文档阅读帮助
聚合API文档阅读帮助 该文基于聚合云数据开放平台的API文档,目的使得开发者能够方便的快速了解我们这个API文档的结构,从而能够经行高效的开发. 该API文档总共有6个大类:国外API.国内API. ...
- Django QuerySet API 文档阅读(3):QuerySet定义(一)
原文地址:QuerySet API reference | Django documentation | Django QuerySet有两个属性,ordered和db: ordered: ...
- Zeal —— API文档离线阅读器
背景 在软件开发的过程中,常常需要查阅多个API文档,但网络环境等因素常常导致在线文档查看用户体验并不佳.为此,介绍一款离线的API文档阅读器,Zeal.Zeal中自配了多种API文档可供查阅,如El ...
- 什么是API? [如何编写和阅读API文档]
随着API在互联网时代中变得越来越普遍,不仅是编程人员会用到,现在也会要求产品经理或互联网运营会调试和对接API.看这篇文章的你可能会使用或开发API,或者两者兼而有之. 因此,对你来说,不仅要了解如 ...
- Splinter入门(十四)API文档
Splinter入门(十四)API文档 1. Browser 2. DriverAPI 3. ElementAPI 4. CookieManager 5. ElementList 6. Request ...
- layer.js 弹窗组件API文档
基础参数 type title content skin area offset icon btn closeBtn shade shadeClose time id shift maxmin fix ...
- 转: HighCharts 详细使用及API文档说明
一.HighCharts开发说明: HighCharts开发实际上配置HighCharts每个部分,比如配置标题(title),副标题(subtitle)等,其中每个部分又有更细的参数配置,比如标题下 ...
- Spring Boot 2.x基础教程:使用Swagger2构建强大的API文档
点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | 翟永超 来源 | didispace.com/spring-boot-learni ...
- Spring Boot 集成 Swagger 生成 RESTful API 文档
原文链接: Spring Boot 集成 Swagger 生成 RESTful API 文档 简介 Swagger 官网是这么描述它的:The Best APIs are Built with Swa ...
最新文章
- Vue轮播图插件---Vue-Awesome-Swiper
- 2020年什么名字最受欢迎?前面“奕辰”你别走
- 寒假集训【1.26】
- Mysql编码教程_mysql编码设置教程 mysql编码要怎么设置呢
- Linux 查看内存状态
- DSP关于存储器读写、IO读写时序图的注意点
- vestacp升级php,升级VestaCP面板PHP版本至PHP7.x
- IDM磁力解析 IDM磁力使用教程
- 机器人(机械臂)动力学建模方法(Euler-Lagrange equation)
- Matlab计算熵权法
- 【保姆级教学】Landsat遥感影像下载
- Android自定义带搜索图标及删除按钮的搜索框SearchEditText
- Autovue Client/Server 部署时的连接问题及诊断策略
- 为什么走线选择50欧姆阻抗
- Debian查看系统版本信息
- Redis的集群配置
- python柱状图zzt_Python torch.diag方法代碼示例
- lucene 中文 完全匹配不是top1
- 事务的隔离 transaction isolation
- WannaCry勒索病毒,企业文件安全保护的启蒙课
热门文章
- python多态_多态是什么?为什么要使用多态?
- 2sin30°在python中如何表示_如何在python中实现以下派生公式?
- java调用keras theano模型_使用Keras / Theano和LSTM进行多标签文本分类
- java 桥接模式_JAVA设计模式之【桥接模式】
- editor修改样式 vue_手摸手Electron + Vue实战教程(三)
- python 拓扑排序 dfs bfs_bfs与dfs的优缺点?
- 逻辑漏洞之密码找回总结
- IIS请求筛选模块被配置为拒绝超过请求内容长度的请求
- springmvc使用freemarker
- 数据结构(一)---顺序表的实现---java版