深刻理解Ember-Data特性(下)

写在前面

         最近比较忙,换了新工做还要学习不少全新的技术栈,并给本身找了不少借口来不去坚持写博客。经常具备讽刺意味的是,更多剩下的时间并无利用而更多的是白白浪费,也许这就是青春吧,挥霍吧,这不是我想要的,既然这样,我还要继续写下去,坚持把博客作好,争取进前100博客,在此谨记。html

                                                                                                         2015年5月7日深夜,于电脑旁。前端

文章索引

JS前端框架之Ember.js系列git

 

2、使用Ember-Data

  为了更好的使用Ember-Data,你就须要使用Store,Store你能够认为是一个内存缓存,Ember-Data使用它去恢复和保存数据模型。事实上,Store还负责从服务端获取数据,经过已绑定的Adapter。github

  还能够自定义Adapter:json

  或者自定义serializer:api

  这里仅仅是指出自定义场景,接下来会详细分析。数组

Model中获取数据

  下面列举两种简单的获取数据方式:缓存

  1. Store.find(‘mainMenu’); 这种方式是试图获取mainMenu类型的全部数据。
  2. Store.find(‘mainMenu’,’JSFlotJAgent’);这种方式是试图获取类型为mainMenu, id为“JSFlotJAgent”类型的数据。

 

  更多例子请参考:http://emberjs.com/api/data/classes/DS.Store.html前端框架

标识模型关系

         以上模型中的mainMenu以及Children类型同为mainMenu,造成一个“无限极”树的概念,循环嵌套节点对象,下图展现了模型中mainMenu和Chart的关系图:服务器

注:上图中的OneToOne、OneToMany等是有歧义,做者的这幅图应该改成OneToNone、ManyToNone。

  这里mainMenu有一个parent节点标识上一层引用关系,一个children节点来表示孩子节点的集合,最后还有一个一对一的chart来表示图表数据。能够将chart理解为一个节点中的主要内容,parent和children则表示当前节点所在位置、关联关系,有些相似于两个指针分别指向父节点和孩子节点。

  接下来一节咱们详细分析Ember-Data中的模型关系。

3、Ember-Data模型关联关系

         Ember-Data支持多种数据关系类型,这些关系类型用来指望从数据端返回的数据类型结构,接下来咱们来详细分析这些API的做用。

 

理解Ember-Data关系模型

         Ember-Data定义了5中关系模型,其中三种是真正的类型,另外两种能够理解为特殊例子。

注:图中第二行的OneToNone替换成OneToOne,做者这里多是笔误。

  其中,上一节咱们讲过,Ember-Data中有不少约定,例如定义的属性要Camel风格(如modelA),列表数组属性结尾要用s(如modelAs),全部id要惟一性,这样便于读取从服务端传来的JSON Hash对象。

理解Ember-Data边缘(sideloaded)加载

  边缘式加载的是经过增长数据层级来分步加载(能够理解为先加载第一层次的数据集合,而后按需加载子一级的数据集合)。

  咱们先来看下Model的定义:

  这是一个典型的文章及评论的结构,即一个文章包含有多条评论,一条评论属于一篇文章。

  下面来让咱们看看边缘式加载是如何工做的:

  当请求类型全部数据时,Ember-Data发现仓库中没有此类数据,则向服务器发起请求,而服务器仅仅返回文章内容及评论id(能够理解为仅仅返回评论的预览,而非一条评论的所有信息),而后当再次请求评论详情时,服务端返回评论的真实信息。

  你能够在第一次请求数据时,让服务端返回全部数据:(而不是等待评论请求时再返回)

  注:这样的场景下,若是用户没有查看评论,则评论永远也没有被显示出来,也就是说数据可能毫无心义的加载了。

  固然这还要取决于你的数据场景,可能这样模式并不适合你,这样作会产生更多的HTTP请求,但同时又减少了“可用”数据的返回量,如何取舍还需仔细分析,固然你也能够自定义如何返回数据。

4、定制Adapter和Serializer

  这里Ember提供了三种基本的重写Adapter的场景:

  1. 服务端API传来的数据对数据类型没有通用的标准。
  2. 服务端API传来的数据不一样于你定义的数据类型。
  3. 重写Adapter并保留Serializer,来保证服务端传来的Json数据顶级结构中的类型与你定义的类型不一样,而子类型相同。

 

定制Adapter

  下面来让咱们看下这种场景:

  在咱们上一节的数据类型中,mainMenu包含一个一对一的Chart类型,如今的需求是但愿能够设置Chart的Timespan来部分获取Chart数据,若是没有设置则默认为10minutes。

  首先,从DS.RESTAdapter中扩展一个类型,而且要遵循Adapter的命名规范(XXXXAdapter这种模式必须遵循)。

  而后,能够重写以下的方法:

  对于咱们目前的需求来讲,咱们仅仅须要重写find()方法便可,方法中将进行一个HTTP请求。

  其中,重要的是用Timespan重组http请求,已达到咱们的目的。

  更多请参考:http://guides.emberjs.com/v1.11.0/models/customizing-adapters/

定制Serializer

  相对于RESTSerializer而言,咱们给出以下的非标准数据模型:

  在这个返回类型中,user_name、account_name、user_role是非标准的数据相对RESTSerializer来讲。并且最顶层的属性名称user_model也不符合。

  咱们能够重写Adapter中的方法以达到咱们的目的:

         这里咱们须要重写normalize方法为了解决user_name、account_name、user_role非标准化问题,重写typeForRoot方法解决user_model问题。

定制URL

         你能够定制Adapter的ULR访问类型以及转换定义,下面是一个很好的例子:

  最终将访问以下网址:http://api.myapp.com/json/v1/mainMenus

FAQ

  1. 使用Store存储数据的优点是否能结合Filter?

Store能自动cache数据并保持数据同一性,经过id属性。而且容许用户使用Filter来过滤不须要的数据。

  1. Ember-Data如何通知新数据已经到达?

当你使用store.find()时,数据会自动更新RecordArray,任何计算属性或者监听在RecordArray上都将得到通知。若是你不须要请求而且要加载数据的话,可使用Store.push或者pushPayload 来向Store中推送数据,这样Store也会得到监听事件的触发。例如SSE或WebSocket场景。

引用

  Ember-Data更新日志:https://github.com/emberjs/data/blob/master/TRANSITION.md

  参考书目:《Ember.js In Action》 

相关文章
相关标签/搜索