写在前面
最近比较忙,换了新工作还要学习很多全新的技术栈,并给自己找了很多借口来不去坚持写博客。常常具有讽刺意味的是,更多剩下的时间并没有利用而更多的是白白浪费,也许这就是青春吧,挥霍吧,这不是我想要的,既然这样,我还要继续写下去,坚持把博客做好,争取进前100博客,在此谨记。
2015年5月7日深夜,于电脑旁。
文章索引
综述
Ember-Data对于Web应用程序来说是一个ORM Framework。Ember-Data直接作用于服务端数据,允许您更改格式化服务端数据,最小化客户端展现的数据。您可以通过自定义adatpters和serializer来处理服务端的数据。
Ember.js核心生态系统/架构图
Runtime负责依据Model中的status状态更新View, 以建立一个由Model直接绑定View的一种方式。类似于Backbone.js的Collection,Ember.js中是用App.Store作为数据仓库来函缓存以及加载数据。
Metamorph.js
即将用HTMLBar代替,Ember团队成员认为此模块是过于“笨重的脚本标签,现阶段我们使用这些标签追踪Dom中反馈的值,HTMLBar相当于HTML5和Handlebars组成的语法组件。
HTMLBar:http://oscarlodriguez.nl/Labs/htmlbars/#/
Handlebars.js
Handlebars 是 JavaScript 一个语义模板库,通过对view和data的分离来快速构建Web模板。它采用"Logic-less template"(无逻辑模版)的思路,在加载时被预编译,而不是到了客户端执行到代码时再去编译, 这样可以保证模板加载和运行的速度。
RSVP.js
RSVP.js提供一个简单的工具来管理异步代码,简单来说它是实现了Promises/A+的一个小型框架。
ES6也引入了Promises,当你发起一个异步请求,并绑定了.when(), .done()等事件处理程序时,其实就是在应用promises模式。
官网地址:https://github.com/tildeio/rsvp.js
Backburner.js
一个重写Ember.js Run Loop的一般框架。
作者加入了Ember.js团队:
Backburner.js and the run loop. Erik is joining us from San Francisco and I'm very excited to hear more.
Github地址:https://github.com/ebryn/backburner.js
一、Ember-Data数据缓存
Ember-Data Model object模型对象对于Ember-Data作为一个服务来定义Model中含有的属性以及属性的类型。
定义Ember-Data模型
MainMenu类扩展了DS.Model模型,定义了成员并指定了成员的类型和所属关系,模型中并未定义id属性,id属性是Ember-Data中隐式定义的方便数据仓库(Store)索引数据,如果重写此id属性则会有错误提示。从DS.Model中扩展出自己的Model好处是,可以继承一些列的绑定、监测函数(observers)、和计算属性等API,后续章节会详细分析这些属性。
Ember-Data是一种同一性数据映射
一个普通的基于JavaScript的Web应用通过Json或者REST接口获得数据,并将数据保存在DOM树中,虽然这样能快速的更新View,但是开发人员需要确保旧数据将被从DOM树中移除,以保证Web程序性能。
Ember-Data通过建立数据仓库来解决这个问题,并将数据缓存起来,然后通过唯一标识“id”来获取和更新数据,Ember-Data确保数据的同一性。
下图显示Ember-Data管理它的数据以及同一性映射是如何工作的:
第一次请求id为ABC的数据时,Ember-Data仓库中并没有数据,Ember-Data返回一个带有id和Status标识的“空数据”,同时向服务器发起请求。当收取到服务器返回值时,Ember-Data先将数据缓存下来,然后将变更的结果通知View(或者可以说View自动监听了Model的变化,稍后会做模型绑定分析)。
第二次发起同样的请求时,Ember-Data发现其仓库内含有这样的数据,则直接返回其数值,而不再向服务器发起请求。
模型之间的关联关系
由于模型之间的关系通常是散乱的、纠结的、关联的、非标准的等,Ember-Data通过提供功能和集成点来确保你能将这些关联的结构更好的组织起来。
Ember-Data通过唯一标识id来确保组织的关系,下图来显示Ember-Data是如何通过Id来管理组织之间的关系的:
默认情况下,RESTAdapter期望你的Key是能是camelized风格,首字母要小写,id的值要大写,并且如果返回的数据类型是数组或列表,则应该加后缀s。
你还可能看到“children”中并没有真正的数据,而仅仅只是含有指示到子类数据的id,Ember-Data通过id来查找子元素的值。
Question: 什么子类的parent要绑定到父类?
答:仅仅是数据结构上的定义。
模型的之中的状态和事件
正因为大多数Ember-Data在程序中的行为是异步的,Ember-Data的模型内置了状态管理器,来维护数据状态,当数据发生改变时。Ember-Data在内部使用这些状态,来向Web程序提供数据。例如,当你想在界面上使用加载滚动条时,这些方法/属性将变的非常有用。
而且,通过扩展DS.Model,Ember内置了转换函数能使开发者能在Controller或者View中调用这些功能。
Ember-Data 的状态:
注意:这些属性还可以组合使用,例如当isDirty和isDeleted都为true时表示:本地数据已删除,但还为收到服务端传来的删除确认信息。
Ember-Data 事件列表:
你可以通过 Model.on(‘didLoad’, function() { console.log(“Loaded!”)});来订阅事件通知,相当于在didLoad上注册一个事件以便监听Model发生的变化。
下图是一个部分的状态流程图:
当请求数据时,状态为isLoading,当数据返回到数据仓库中,状态为isLoaded,如果本地对数据做修改则状态变更为isDirty状态,当保存数据时,状态为isSaving, 服务端返回OK(例如http 200),状态由isSaving变更为isLoaded。或者isError。
以上仅仅是常用的API,更多详情请参考:http://emberjs.com/api/data/classes/DS.Store.html
未完待续,请参考《深入理解Ember-Data特性(下)》