一、概述

默认的,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有一个名为lastNameOfPersonkey,并且期望的属性名字是简单的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]
}
}

postComments可以通过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,booleandate可能会不够。例如,一个服务器可能返回一个不标准的日期格式。

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的更多相关文章

  1. Android 自定义列表指示器

    在联系人界面 可以看到这种界面 手指快速滑动右边滑动条时 可以显示相应的字母图标 android里提供了android.widget.SectionIndexer这个接口去实现该效果 可是只能显示字母 ...

  2. 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 ...

  3. Database and models

    Database and models The database Now that we have the Album module set up with controller action met ...

  4. 7.9 Models -- Connection to An HTTP Server

    一.概述 1. 如果你的Ember应用程序需要从一个HTTP服务器加载JSON数据,在你的服务器返回的任何格式中,配置Ember Data的过程将会加载records. 2. store使用一个被称为 ...

  5. 7.4 Models -- Pushing Records into the Store

    一.概述 1. store是作为一个所有records的缓存,这些records已经被你的应用程序加载.在你的app中如果你的路由或者一个controller请求一条record,如果它在缓存中这个s ...

  6. 7.1 Models -- Introduction

    一.概述 1. 模型是表示应用程序呈现给用户的底层数据的对象.不同的应用程序有不同的模型,这取决于它们正在试图解决什么问题. 2. 例如,一个照片共享应用程序可能有一个Phone模型来代表一个特殊的照 ...

  7. 7.2 Models -- Defining Models

    一.概述 1. 模型是一个类,它定义了你呈现给用户的数据的属性和行为.用户希望如果他们离开你的应用程序,并返回后(或如果他们刷新页面)看到的任何东西应该被一个model代表. 2. 确保在ember. ...

  8. 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 ...

  9. 设计模式(七): 通过转接头来观察"适配器模式"(Adapter Pattern)

    在前面一篇博客中介绍了“命令模式”(Command Pattern),今天博客的主题是“适配器模式”(Adapter Pattern).适配器模式用处还是比较多的,如果你对“适配器模式”理解呢,那么自 ...

随机推荐

  1. PCL—低层次视觉—关键点检测(iss&Trajkovic)

    关键点检测往往需要和特征提取联合在一起,关键点检测的一个重要性质就是旋转不变性,也就是说,物体旋转后还能够检测出对应的关键点.不过说实话我觉的这个要求对机器人视觉来说是比较鸡肋的.因为机器人采集到的三 ...

  2. [转]F5负载均衡名词LTM和GTM

    LTM就是本地流量管理,也就是通常所说的服务器负载均衡.可以将多个提供相同服务的设备(pool)虚拟成一个逻辑设备,供用户访问.也就是说,对于用 户来讲,看到的只有一个设备,而实际上用户是服务请求是在 ...

  3. JavaScript 异步进化史

    前言 JS 中最基础的异步调用方式是 callback,它将回调函数 callback 传给异步 API,由浏览器或 Node 在异步完成后,通知 JS 引擎调用 callback.对于简单的异步操作 ...

  4. laravel with 渴求式加载指定字段

    在使用 Laravel 的关联查询中,我们经常使用 with 方法来避免 N+1 查询,但是 with 会将目标关联的所有字段全部查询出来,对于有强迫症的我们来说,当然是不允许的. 这时候我们可以使用 ...

  5. PhoneGap安装配置

    PhoneGap是一能够让你用普通NewsShow的web技术编写出能够轻松调用API接口和进入应用商店的HTML5应用开发平台.是唯一的一个支持7个平台的开源移动框架.它的优势是无以伦比的:开发成本 ...

  6. 【转】常用html转义符,JavaScript转义符

    HTML字符实体(Character Entities),转义字符串(Escape Sequence) 为什么要用转义字符串? HTML中<,>,&等有特殊含义(<,> ...

  7. jquery的$.each如何退出循环和退出本次循环

    https://api.jquery.com/jQuery.each/ We can break the $.each() loop at a particular iteration by maki ...

  8. IntelliJ IDEA最新版完美破解激活

    IntelliJ IDEA号称是目前最好最强最智能的Java IDE,默认已经集成了几乎所有主流的开发工具和框架.目前最新版为2017.2.5(2017.2.5已经不是最新,但是写教程的时候2017. ...

  9. VS远程调试亲历

    背景: 很多情况下本地开发没有问题,可放到服务器就有问题(更气人的是测试环境时也行可就是生产环境不行!) 1.想到可能是服务器环境不对,Web服务器版本不对 2.有文件读写是不是文件夹权限 3.Web ...

  10. Ubuntu 下 kdevelop下 怎么向主函数传递参数

    1.打开工程 2.点击窗口上的运行”--“配置启动器” 3.左栏选择要传递参数的工程名,在参数一栏中,输入参数“ubuntu.png”,再输入“工作目录”.点击OK,运行就可以了.