Ember.js 入门指南——model简介2

本文接上一篇《Ember.js 入门指南——model简介1》。

2,核心概念

声明:下面简介内摘抄至http://www.emberjs.cn/guides/models/#toc_

1,store

store是应用存放记录的中心仓库。你可以认为store是应用的所有数据的缓存。应用的控制器和路由都可以访问这个共享的store;当它们需要显示或者修改一个记录时,首先就需要访问store。

DS.Store的实例会被自动创建,并且该实例被应用中所有的对象所共享。

store可以看做是一个缓存。在下面的cache会结合store介绍。

下面的例子结合firebase演示:

创建路由和model:

ember g route store-example
ember g model article
//   app/models/article.js
 
import DS from ‘ember-data‘;
 
export default DS.Model.extend({
            title: DS.attr(‘string‘),
            body: DS.attr(‘string‘),
            timestamp: DS.attr(‘number‘),
            category: DS.attr(‘string‘)
});

这个就是model,本章要讲的内容就是它!为何没有定义id属性呢?Ember会默认生成id属性。

我们在路由的model回调中获取远程的数据,并显示在模板上。

//  app/routes/store-example.js
 
import Ember from ‘ember‘;
 
export default Ember.Route.extend({
            model: function() {
                        // 从store中获取id为JzySrmbivaSSFG6WwOk的数据,这个数据是我在我的firebase中初始化好的
                        return this.store.find(‘article‘, ‘-JzySrmbivaSSFG6WwOk‘);
            }
});

find方法的第一个参数是model类名,第二个参数对象的id属性值。记得id属性不需要在model类中手动定义,Ember会自动为你定义。

<h1>{{model.title}}</h1>
 
<div>
{{model.body}}
</div>

页面加载之后可以看到获取到的数据。

下面是我的firebase上的部分数据截图。

可以看到成功获取到id为-JzySrmbivaSSFG6WwOk的数据。更多关于数据的操作在后面会详细介绍。

2,model

有关model的概念前面的简介已经介绍了,这里不再赘述。

model定义:

model是由若干个属性构成的。attr方法的参数指定属性的类型。

export default DS.Model.extend({
            title: DS.attr(‘string‘),  //  字符串类型
            flag: DS.attr(‘boolean‘), //  布尔类型
            timestamp: DS.attr(‘number‘),  //  数字类型
            birth: DS.attr(‘date’)  //日期类型
});

模型也声明了它与其他对象的关系。例如,一个Order可以有许多LineItems,一个LineItem可以属于一个特定的Order。

App.Order = DS.Model.extend({
  lineItems: DS.hasMany(‘lineItem‘)
});
 
App.LineItem = DS.Model.extend({
  order: DS.belongsTo(‘order‘)
});

这个与数据的表之间的关系是一样的。

3,record

record是model的实例,包含了从服务器端加载而来的数据。应用本身也可以创建新的记录,以及将新记录保存到服务器端。

记录由以下两个属性来唯一标识:

1,模型类型

2,一个全局唯一的ID

比如前面的实例article就是通过find方获取。获取到的结果就是一个record。

4,adapter

适配器是一个了解特定的服务器后端的对象,主要负责将对记录(record)的请求和变更转换为正确的向服务器端的请求调用。

例如,如果应用需要一个ID为1的person记录,那么Ember Data是如何加载这个对象的呢?是通过HTTP,还是Websocket?如果是通过HTTP,那么URL会是/person/1,还是/resources/people/1呢?

适配器负责处理所有类似的问题。无论何时,当应用需要从store中获取一个没有被缓存的记录时,应用就会访问适配器来获取这个记录。如果改变了一个记录并准备保存改变时,store会将记录传递给适配器,然后由适配器负责将数据发送给服务器端,并确认保存是否成功。

5,cache

store会自动缓存记录。如果一个记录已经被加载了,那么再次访问它的时候,会返回同一个对象实例。这样大大减少了与服务器端的往返通信,使得应用可以更快的为用户渲染所需的UI。

例如,应用第一次从store中获取一个ID为1的person记录时,将会从服务器端获取对象的数据。

但是,当应用再次需要ID为1的person记录时,store会发现这个记录已经获取到了,并且缓存了该记录。那么store就不会再向服务器端发送请求去获取记录的数据,而是直接返回第一次时候获取到并构造出来的记录。这个特性使得不论请求这个记录多少次,都会返回同一个记录对象,这也被称为Identity Map(标识符映射)。

使用标识符映射非常重要,因为这样确保了在一个UI上对一个记录的修改会自动传播到UI其他使用到该记录的UI。同时这意味着你无须手动去保持对象的同步,只需要使用ID来获取应用已经获取到的记录就可以了。

3,架构简介

应用第一次从store获取一个记录时,store会发现本地缓存并不存在一份被请求的记录的副本,这时会向适配器发请求。适配器将从持久层去获取记录;通常情况下,持久层都是一个HTTP服务,通过该服务可以获取到记录的一个JSON表示。

如上图所示,适配器有时不能立即返回请求的记录。这时适配器必须向服务器发起一个异步的请求,当请求完成加载后,才能通过返回的数据创建的记录。

由于存在这样的异步性,store会从find()方法立即返回一个承诺(promise)。另外,所有请求需要store与适配器发生交互的话,都会返回承诺。

一旦发给服务器端的请求返回被请求记录的JSON数据时,适配器会履行承诺,并将JSON传递给store。

store这时就获取到了JSON,并使用JSON数据完成记录的初始化,并使用新加载的记录来履行已经返回到应用的承诺。

下面将介绍一下当store已经缓存了请求的记录时会发生什么。

在这种情形下,store已经缓存了请求的记录,不过它也将返回一个承诺,不同的是,这个承诺将会立即使用缓存的记录来履行。此时,由于store已经有了一份拷贝,所以不需要向适配器去请求(没有与服务器发生交互)。

models、records、adapters、store是你必须要理解的概念。这是Ember Data 最核心的东西。

有关于上述的概念将会在后面的文章一一用代码演示。理解了本文model这一整章的内容都不是问题了!!!

时间: 2024-10-20 13:50:35

Ember.js 入门指南——model简介2的相关文章

Ember.js 入门指南——路由简介

从本文开始,将为大家介绍路由(route),如果你看过前面的<Ember.js 入门指南--{{link-to}} 助手>这篇文章应该初步了解了route.不过在这篇文章中只是简单介绍了路由是定义.路由层次,更深入的route将从本文开始逐一介绍. 当用户使用你的应用时,应用要在不同的状态之间切换.Ember提供了很多工具用于管理那些因应用规模改变而改变的状态. 讲route前先了解URL,在应用中大概会会有如下方式设置URL: 用户第一次加载应用的时: 用户手动改变URL,比如点击按钮之后跳

Ember.js 入门指南——总目录

Ember.js 是什么?我想对于想学习它的人应该知道它是个什么东西,如果你想了解那就赶紧去 Google 或者百度,本系列教程是通过学习官网教程然后摘抄个人觉得比较重要的部分,加上学习实例整合而成,如有疏漏欢迎提出修改意见,一起成长! Ember官网:http://emberjs.com/ 教程官网:http://guides.emberjs.com/v2.0.0/ 在此简单介绍下 Ember: Ember是一个雄心勃勃的Web应用程序,消除了样板,并提供了一个标准的应用程序架构的JavaSc

Ember.js 入门指南——控制器(controller)

ember new chapter5_controllers cd chapter5_controllers ember server 从本篇开始进入第五章控制器,controller在Ember2.0开始越来越精简了,职责也更加单一--处理逻辑. 下面是准备工作. 从新创建一个Ember项目,仍旧使用的是Ember CLI命令创建. 在浏览器执行项目,看到如下信息说明项目搭建成功. Welcome to Ember 1,控制器简介 控制器与组件非常相似,由此,在未来的新版本中很有可能组件将会完

Ember.js 入门指南——属性传递

1,传递参数到组件上 每个组件都是相对独立的,因此任何组件所需的数据都需要通过组件的属性把数据传递到组件中. 比如上篇<Ember.js 入门指南--组件定义>的第三点"{{component item.pn post=item}}"就是通过属性post把数据传递到组件foo-component或者bar-component上.如果在index.hbs中是如下方式调用组件那么渲染之后的页面是空的. {{component item.pn}} 请读者自己修改index.hbs

Ember.js 入门指南——包裹内容

准备工作: ember g route wrapping-content-in-component-route        ember g component wrapping-content-in-component 有些情况下,你需要定义一个包裹其他模板提供的数据的组件.比如下面的例子: <!--  app/templates/components/wrapping-content-in-component.hbs  -->   <h1>{{title}}</h1>

Ember.js 入门指南——异步路由

本文将为你介绍路由的高级特性,这些高级特性可以用于处理项目复杂的异步逻辑. 关于单词promises,直译是承诺,但是个人觉得还是使用原文吧.读起来顺畅点. 1,promises(承诺) Ember的路由处理异步逻辑的方式是使用promises.简而言之,promises就是一个表示最终结果的对象.这个对象可能是fulfill(成功获取最终结果)也可能是reject(获取结果失败).为了获取这个最终值,或者是处理promises失败的情况都可以使用then方法,这个方法接受两个可选的回调方法,一

Ember.js 入门指南——路由定义

当你的应用启动的时候,路由器就会匹配当前的URL到你定义的路由上.然后按照定义的路由层次逐个加载数据.设置应用程序状态.渲染路由对应的模板. 1,基本路由 在app/router.js的map方法里定义的路由会映射到当前的URL.当map方法被调用的时候方法体内的route方法就会创建路由. 下面使用Ember CLI命令创建两个路由: ember generate route about ember generate route favorites 命令执行完之后你可在你的项目目录app/ro

Ember.js 入门指南--目录

本系列文章全部从(http://ibeginner.sinaapp.com/)迁移过来,欢迎访问原网站. Ember.js 是什么?我想对于想学习它的人应该知道它是个什么东西,如果你想了解那就赶紧去 Google 或者百度,本系列教程是通过学习官网教程然后摘抄个人觉得比较重要的部分,加上学习实例整合而成,如有疏漏欢迎提出修改意见,一起成长! Ember官网:http://emberjs.com/ 教程官网:http://guides.emberjs.com/v2.0.0/ 在此简单介绍下 Emb

Ember.js 入门指南——模板渲染

路由的另一个重要职责是渲染同名字的模板. 比如下面的路由设置,posts路由渲染模板posts.hbs,路由new渲染模板posts/new.hbs. Router.map(function() {      this.route('posts', function() {      this.route('new');   }); }); 每一个模板都会渲染到父模板的{{outlet}}上.比如上面的路由设置模板posts.hbs会渲染到模板application.hbs的{{outlet}}