模型篇 Introduction下

Covention Over Configuration with JSON API

通过遵循Ember的约定,你可以显著的减少手动coding的工作量。如果在team中每个member都遵守统一的约定,那么项目代码就会易维护。

相较于拟定一系列临时的约定,Ember Data已经提供了基于JSON API的接口协议。 JSON API是一个前后端通信的数据格式标准。

(这段文字的作用就是引入了JSON API,读者可下去自行百度what is JSON API)

...

其他的文字没有特别的意义,不翻译了

Models

在Ember Data中,每一个model对象都是继承自Model类的子类实例。每一个model对象中都定义了属性,关联关系和数据的作用。

Model中可以描述从服务器返回的属性的数据类型。比如,Personmodel中定义了一个firstName属性 ---- 它是个string,还定义了一个birthday属性 ---- 它是个date:

app/models/person.js

importDSfrom'ember-data';

export defaultDS.Model.extend({

firstName:DS.attr('string'),

birthday:DS.attr('date')

});

model中同样也可以描述它与其他对象之间的关系。比如, 一个order中有很多line-items,一个line-items可以属于某个order:

(order--订单;line-items--可以理解为具体的商品)

app/models/order.js

importDSfrom'ember-data';

export defaultDS.Model.extend({

lineItems:DS.hasMany('line-item')

});

app/models/line-item.js

importDSfrom'ember-data';

export defaultDS.Model.extend({

order:DS.belongsTo('order')

});

Model(model的实例是带有实际数据的) 并没有包含实际的数据,它只是定义了属性,关联关系和实例中的数据行为等。但是!!我们可以把model对应的实例称为records-- 它是包含具体数据的对象。

Records

record是一个包含实际数据的model对象实例, 它所包含的数据来自后端服务器。当然,在 前端也可以生成一条 record,然后把该条 record 保存到服务器去。

每一条 record通过它的type和唯一的ID来区分。

比如,你现在正在编写一个通讯录应用,你或许会定义一个personmodel。每一个person实例都会有个type属性 和 一个ID属性:

this.store.findRecord('person',1); // { id: 1, name: 'steve-buscemi' }

ID通常是在该属性第一次被保存进数据库时后端赋予的。不过我们也可以在客户端来生成 ID。

Adapter

adapter可以把Ember对数据的请求(比方说:findRecord方法)翻译成我们的http请求。

比如,如果我们的应用想要获取 ID 为 1 的Personrecord,那么Ember要怎么载入这条数据? 通过HTTPorWebSocket?如果是HTTP,那么URL是/person/1or/resources/people/1?

adapter会负责来解决上述所有问题。当应用需要的数据在store中没有的时候,那么store就会询问adapter。如果你修改一条record并且保存了它,那么store就会将它递给adapter然后adapter会将对应的数据发送到服务器并且确认请求状态。

adapter使你可以完全忽略远程接口的实现方式,你只需要关注业务代码就可以了。

Caching

store会自动把record缓存下来。如果一条record之前被load过了,那么当第二次再需要它的时候,则会从store的缓存中返回该record。这样做可以减少数据在 客户端/服务器 之前的传递次数,也能让UI迅速得以渲染。

比如,你的应用将会第一次索取一个ID为1的personrecord,这时该数据将从服务器获取。

但是,下次你的应用程序再索取ID为1的person时,store会注意到它已经从服务器load并缓存了该信息。 它不会发送请求,而是从缓存中为你的应用程序返回ID为1的personrecord。 此功能 - 我们可以把它成为身份映射

使用身份映射非常重要,因为它可以确保你在UI的某个部分所做的更改会传播到UI的其他部分。 这也意味着你不必手动保持记录同步,你需要做的就是根据ID获取你的数据,而不必担心应用的其他部分是否已经请求并加载它。

从缓存中获取数据的一个缺点就是,可能会导致缓存中的数据是陈旧的。 为了防止此陈旧数据长期存在问题,Ember Data会在每次从store返回缓存记录时都会自动发出一个请求。 当新数据被载入进入时,record会被更新,这时模版也会同步渲染。

Architecture Overview

当你的应用第一次向store索取record时,store会发现它没有本地副本并向adapter所要它。 你的adapter将从持久层中检索记录; 通常持久层指的是后端的服务器。

如上图所示,adapter若无法立即返回请求的record,就会向须向服务器发出异步请求,并且只有在该请求完成加载时才创建record。

由于这一过程是异步的,store会立即返回一个promise对象。类似的,store中所有的与adapter交互的方法都会返回 Promise。

一旦,服务器返回了请求成功的响应并返回JSON payload,adapter就会 resolvepromise,并把拿到的JSON数据交给 store。

然后store将会使用该JSON数据初始化record,并且将promiesresolve 后返回到你的应用中。

接下来,我们看一下如果store中已经有了某条record的缓存,那么获取数据的流程是什么样的:

在这种情况下,由于 store 已经知道该 record 在缓存中存在,那么它会立即把promiseresolve,并且不会询问adapter。

Model, record,adapter 和 store 是需要你理解的Ember Data的核心概念。后续的章节将会带你深入了解它们。

本节完

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180820G18CDJ00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券