一、概述

默认的,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. C# 泛型的简单讲解和应用

    泛型 什么是泛型 泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能.泛型将类型参数的概念引入 .NET Framework,类型参数使得设计如下类和方法成为可能:这些类和方法 ...

  2. Elasticsearch学习之快速入门案例

    1. document数据格式 面向文档的搜索分析引擎 (1)应用系统的数据结构都是面向对象的,复杂的(2)对象数据存储到数据库中,只能拆解开来,变为扁平的多张表,每次查询的时候还得还原回对象格式,相 ...

  3. 九度OJ小结

    1. 高精度问题 可参考题目 题目1137:浮点数加法   http://ac.jobdu.com/problem.php?pid=1137 对于高精度问题可以考虑使用结构体.上述为浮点数加法,因此该 ...

  4. Repository(资源库)模式

    Repository(资源库) 协调领域和数据映射层,利用类似于集合的接口来访问领域对象 定义(来自Martin Fowler的<企业应用架构模式>): Mediates between ...

  5. jquery validator

    jQuery.validate是一款非常不错的表单验证工具,简单易上手,而且能达到很好的体验效果,虽然说在项目中早已用过,但看到这篇文章写得还是不错的,转载下与大家共同分享. 一.用前必备 官方网站: ...

  6. 使用spring提供的ReflectionUtils简化项目中反射代码的复杂性

    在项目中有时候我们会使用到反射的功能,如果使用最原始的方法来开发反射的功能的话肯能会比较复杂,需要处理一大堆异常以及访问权限等问题.spring中提供了ReflectionUtils 这个反射的工具类 ...

  7. facebook login issue

    If enable the facebook account in settings, when change account can't open the session. -(void)fbRes ...

  8. linux系统下kvm虚拟机的安装

    一 KVM虚拟机简介 KVM是kernel-based Virtual Machine的简称,目前已成为学术界的主流VMM之一.KVM的虚拟化需要硬件支持(如Intel VT技术或者AMD V技术) ...

  9. vuejs学习资料

    Vue.js 是一个轻巧.高性能.可组件化的MVVM库,同时拥有非常容易上手的API,让编写动态的UI界面变得轻松简单. 这里是我整理的相关学习资料: vue.js 中文api vue.js gith ...

  10. iOS - 开源框架、项目和学习资料汇总(其他篇)

    数据库 1. FMDB – sqlite的工具, 多线程FMDatabaseQueue实例,FMDB数据库的使用演示和封装工具类.GXDatabaseUtils – 在FMDB基础上的工具.2. re ...