7.8 Models -- The Rest Adapter
一、概述
默认的,store将会使用 DS.RESTAdapter来加载和存储records。这个RESTAdapter假定URLS和JSON关联每一个model是约定好的;这意味着,如果你遵循这个规则,你将不需要配置这个adapter或者为了启动编写任何代码。
二、URL Conventions
1. 基于model的name,这个REST adapter足够的聪明来确定和它通信的URLS。例如,如果你通过一个ID请求一个Post:
store.findRecord('post', 1).then(function(post) {
});
2. 这个REST适配器将会自动发送一个Get请求到/posts/1。
3. 对于多个word名字,这个REST适配器将会使用lower_snake_case。
4. 你可以采取的action,在REST适配器中,映射到下面的URL:
Action | HTTP Verb | URL |
---|---|---|
Find Record | GET | /posts/123 |
Find All | GET | /posts |
Update | PUT | /posts/123 |
Create | POST | /posts |
Delete | DELETE | /posts/123 |
5. Pluralization customization(多元化定制)
可以通过Ember.Inflector.inflector指定不规则的或者不可数的多元化:
var inflector = Ember.Inflector.inflector; inflector.irregular('person', 'people');
inflector.uncountable('advice');
这将告诉这个REST适配器,对于person的请求应该去请求/people/1而不是/persons/1。
6. Endpoint path customization(终端的路径定制)
通过设定在适配器中的namespace属性,终端的路径可以被加上一个命名空间前缀:
app/adapters/application.js
export default DS.RESTAdapter.extend({
namespace: 'api/1'
});
person的请求现在会导航到http://emberjs.com/api/1/people/1。
7. Host customization(定制主机)
通过设定host属性,一个适配器可以导航到其他的hosts。
app/adapters/application.js
export default DS.RESTAdapter.extend({
host: 'https://api.example.com'
});
请求person现在将会导航到https://api.example.com/people/1。
三、JSON Conventions
1. 当请求一条record,这个REST适配器期望你的服务器返回一个JSON代表这条record,它符合下列惯例。
2. JSON ROOT
(1) 返回的主要record应该在一个命名的根中。例如,如果你从/people/123请求一条record,响应应该被嵌套进一个被称为person的属性中:
{
"person": {
"firstName": "Jeff",
"lastName": "Atwood"
}
}
(2) 在destroyRecord之后或者在deleteRecord并且save之后,这个适配器期望服务器去返回一个空的对象({})。
(3) 如果你没有改变服务器返回的数据的选项,你可以重写这个DS.JSONSerializer#extractDeleteRecord,像这样:
extractDeleteRecord: function(store, type, payload) {
// If the payload is {delete: true}, Ember Data will try to set
// the new properties. Return null so it doesn't try to do that.
return null;
}
3. Attribute Names
(1) 属性名字应该用驼峰命名法。例如,如果你有一个model,像这样:
app/models/person.js
export default DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'), isPersonOfTheYear: DS.attr('boolean')
});
从服务器返回的JSON应该像这样:
{
"person": {
"firstName": "Barack",
"lastName": "Obama",
"isPersonOfTheYear": true
}
}
(2) 不规则的键可以被一个自定义的序列化器映射。如果person有一个名为lastNameOfPerson的key,并且期望的属性名字是简单的lastName,那么为这个model创建一个自定义的序列化器并且重写这个normalizeHash属性:
app/models/person.js
export default DS.Model.extend({
lastName: DS.attr('string')
});
app/serializers/person.js
export default DS.RESTSerializer.extend({
normalizeHash: {
lastNameOfPerson: function(hash) {
hash.lastName = hash.lastNameOfPerson;
delete hash.lastNameOfPerson; return hash;
}
}
});
4. Relationships
(1) 引用其他的rcords应该通过ID。例如,如果你有一个model,它有一个hasMany关系:
app/models/post.js
export default DS.Model.extend({
comments: DS.hasMany('comment', { async: true })
});
JSON应该编码这个关系为一个IDs数组:
{
"post": {
"comments": [1, 2, 3]
}
}
post的Comments可以通过post.get('comments')被加载。对每一个相关的comment这个REST适配器将会发送一个Get请求。
post.get('comments'); // GET /comments/1
// GET /comments/2
// GET /comments/3
(2) 你可以在你的适配器中通过设定coalesceFindRequests 为true阻止发送多个请求:
app/adapters/application.js
export default DS.RESTAdapter.extend({
coalesceFindRequests: true
});
这个REST适配器现在将会发送一个GET请求到/comments?ids[]=1&ids[]=2&ids[]=3。
(3) 在JSON中任何belongsTo关系应该是Ember Data的模型名字的被驼峰化的版本。例如,如果你有一个model:
app/models/comment.js
export default DS.Model.extend({
post: DS.belongsTo('post')
});
这个JSON应该编码这个关系为一个到另一个record的ID:
{
"comment": {
"post": 1
}
}
(4) 如果需要这些命名约定可以被重写,通过实现keyForRelationship方法可以实现:
app/serializers/application.js
export default DS.RESTSerializer.extend({
keyForRelationship: function(key, relationship) {
return key + 'Ids';
}
});
5. Sideloaded Relationships
为了减少必要HTTP请求的数量,你可以在你的JSON响应中sideload额外的records。Sideloaded records存在于JSON root之外,并且被代表一个hash数组:
{
"post": {
"id": 1,
"title": "Node is not omakase",
"comments": [1, 2, 3]
}, "comments": [{
"id": 1,
"body": "But is it _lightweight_ omakase?"
},
{
"id": 2,
"body": "I for one welcome our new omakase overlords"
},
{
"id": 3,
"body": "Put me on the fast track to a delicious dinner"
}]
}
四、Creating custom transformations(创建自定义转化)
1. 在某些情况下,固有的属性类型string,number,boolean和date可能会不够。例如,一个服务器可能返回一个不标准的日期格式。
2. Ember Data可以新注册一个JSON转换器作为属性:
app/transforms/coordinate-point.js
export default DS.Transform.extend({
serialize: function(value) {
return [value.get('x'), value.get('y')];
},
deserialize: function(value) {
return Ember.create({ x: value[0], y: value[1] });
}
});
app/models/cursor.js
export default DS.Model.extend({
position: DS.attr('coordinatePoint')
});
当coordinatePoint从API中被接收的时候,它被期望是一个数组:
{
cursor: {
position: [4,9]
}
}
但是一旦加载到一个model实例,它将作为一个对象行为:
var cursor = this.store.findRecord('cursor', 1);
cursor.get('position.x'); //=> 4
cursor.get('position.y'); //=> 9
如果position被修改并且保存,在转换中它将通过serialize序列化函数并且在JSON中作为一个数组被再次发送。
7.8 Models -- The Rest Adapter的更多相关文章
- Android 自定义列表指示器
在联系人界面 可以看到这种界面 手指快速滑动右边滑动条时 可以显示相应的字母图标 android里提供了android.widget.SectionIndexer这个接口去实现该效果 可是只能显示字母 ...
- How Network Load Balancing Technology Works--reference
http://technet.microsoft.com/en-us/library/cc756878(v=ws.10).aspx In this section Network Load Balan ...
- Database and models
Database and models The database Now that we have the Album module set up with controller action met ...
- 7.9 Models -- Connection to An HTTP Server
一.概述 1. 如果你的Ember应用程序需要从一个HTTP服务器加载JSON数据,在你的服务器返回的任何格式中,配置Ember Data的过程将会加载records. 2. store使用一个被称为 ...
- 7.4 Models -- Pushing Records into the Store
一.概述 1. store是作为一个所有records的缓存,这些records已经被你的应用程序加载.在你的app中如果你的路由或者一个controller请求一条record,如果它在缓存中这个s ...
- 7.1 Models -- Introduction
一.概述 1. 模型是表示应用程序呈现给用户的底层数据的对象.不同的应用程序有不同的模型,这取决于它们正在试图解决什么问题. 2. 例如,一个照片共享应用程序可能有一个Phone模型来代表一个特殊的照 ...
- 7.2 Models -- Defining Models
一.概述 1. 模型是一个类,它定义了你呈现给用户的数据的属性和行为.用户希望如果他们离开你的应用程序,并返回后(或如果他们刷新页面)看到的任何东西应该被一个model代表. 2. 确保在ember. ...
- Raspberry Pi - Huawei HiLink E3256 3G modem to ethernet adapter
Raspberry Pi - Huawei HiLink E3256 3G modem to ethernet adapter This page documents how to configure ...
- 设计模式(七): 通过转接头来观察"适配器模式"(Adapter Pattern)
在前面一篇博客中介绍了“命令模式”(Command Pattern),今天博客的主题是“适配器模式”(Adapter Pattern).适配器模式用处还是比较多的,如果你对“适配器模式”理解呢,那么自 ...
随机推荐
- PCL—低层次视觉—关键点检测(iss&Trajkovic)
关键点检测往往需要和特征提取联合在一起,关键点检测的一个重要性质就是旋转不变性,也就是说,物体旋转后还能够检测出对应的关键点.不过说实话我觉的这个要求对机器人视觉来说是比较鸡肋的.因为机器人采集到的三 ...
- [转]F5负载均衡名词LTM和GTM
LTM就是本地流量管理,也就是通常所说的服务器负载均衡.可以将多个提供相同服务的设备(pool)虚拟成一个逻辑设备,供用户访问.也就是说,对于用 户来讲,看到的只有一个设备,而实际上用户是服务请求是在 ...
- JavaScript 异步进化史
前言 JS 中最基础的异步调用方式是 callback,它将回调函数 callback 传给异步 API,由浏览器或 Node 在异步完成后,通知 JS 引擎调用 callback.对于简单的异步操作 ...
- laravel with 渴求式加载指定字段
在使用 Laravel 的关联查询中,我们经常使用 with 方法来避免 N+1 查询,但是 with 会将目标关联的所有字段全部查询出来,对于有强迫症的我们来说,当然是不允许的. 这时候我们可以使用 ...
- PhoneGap安装配置
PhoneGap是一能够让你用普通NewsShow的web技术编写出能够轻松调用API接口和进入应用商店的HTML5应用开发平台.是唯一的一个支持7个平台的开源移动框架.它的优势是无以伦比的:开发成本 ...
- 【转】常用html转义符,JavaScript转义符
HTML字符实体(Character Entities),转义字符串(Escape Sequence) 为什么要用转义字符串? HTML中<,>,&等有特殊含义(<,> ...
- jquery的$.each如何退出循环和退出本次循环
https://api.jquery.com/jQuery.each/ We can break the $.each() loop at a particular iteration by maki ...
- IntelliJ IDEA最新版完美破解激活
IntelliJ IDEA号称是目前最好最强最智能的Java IDE,默认已经集成了几乎所有主流的开发工具和框架.目前最新版为2017.2.5(2017.2.5已经不是最新,但是写教程的时候2017. ...
- VS远程调试亲历
背景: 很多情况下本地开发没有问题,可放到服务器就有问题(更气人的是测试环境时也行可就是生产环境不行!) 1.想到可能是服务器环境不对,Web服务器版本不对 2.有文件读写是不是文件夹权限 3.Web ...
- Ubuntu 下 kdevelop下 怎么向主函数传递参数
1.打开工程 2.点击窗口上的运行”--“配置启动器” 3.左栏选择要传递参数的工程名,在参数一栏中,输入参数“ubuntu.png”,再输入“工作目录”.点击OK,运行就可以了.