Ember.js 入门指南——定义模型

model也是一个类,它定义了向用户展示的属性和数据行为。model的定义非常简单,只需要继承DS.Model类即可,或者你也可以直接使用Ember CLI命令创建。比如使用命令ember g model person定义了一个model类person。

//  app/models/person.js
 
import DS from ‘ember-data‘;
 
export default DS.Model.extend({
 
});

这个是个空的model,没有定义任何属性。有了model类你就可以使用find方法查找数据了。

1,定义属性

上面定义的model类person还没有任何属性,下面为这个类添加几个属性。

//  app/models/person.js
 
import DS from ‘ember-data‘;
 
export default DS.Model.extend({
       firstName: DS.attr(),
       lastName: DS.attr(),
       birthday: DS.attr() 
});

上述代码定义了3个属性,但是还未给属性指定类型,默认都是string类型。这些属性名与你连接的服务器上的数据key是一致的。甚至你还可以在model中定义计算属性

//  app/models/person.js
 
import DS from ‘ember-data‘;
 
export default DS.Model.extend({
       firstName: DS.attr(),
       lastName: DS.attr(),
       birthday: DS.attr(),
 
       fullName: Ember.computed(‘firstName‘, ‘lastName‘, function() {
              return `${this.get(‘firstName‘)} ${this.get(‘lastName‘)}`;
       })
});

这段代码在model类中定义了一个计算属性fullName。

2,指定属性类型与默认值

前面定义的model类是没有指定属性类型的,默认情况下都是string类型,显然这是不够的,简单的model属性类型包括:string,number,boolean,date。这几个类型我想不用我解释都应该知道了。

不仅可以指定属性类型,你还可以指定属性的默认值,在attr()方法的第二个参数指定。比如下面的代码:

//  app/models/person.js
 
import DS from ‘ember-data‘;
 
export default DS.Model.extend({
       username: DS.attr(‘string‘),
       email: DS.attr(‘string‘),
       verified: DS.attr(‘boolean‘, { defaultValue: false }),  //指定默认值是false
       //  使用函数返回值作为默认值
       createAt: DS.attr(‘string‘, { defaultValue(){ return new Date(); } })
});

正如代码注释所述的,设置默认值的方式包括直接指定或者是使用函数返回值指定。

3,定义model的关联关系

Ember的model也是有类似于数据库的关联关系的。只是相对于复制的数据库Ember的model就显得简单很多,其中包括一对一,一对多,多对多关联关系。这种关系是与后台的数据库是相统一的。

1,一对一

声明一对一关联使用DS.belongsTo设置。比如下面的两个model。

//  app/models/user.js
import DS from ‘ember-data‘;
 
export default DS.Model.extend({
  profile: DS.belongsTo(‘profile’);
});
//  app/models/profile.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  user: DS.belongsTo(‘user’);
});
2,一对多

声明一对多关联使用DS.belongsTo(多的一方使用)和DS.hasMany(少的一方使用)设置。比如下面的两个model。

//  app/models/post.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  comments: DS.hasMany(‘comment’);
});

这个model是一的一方。下面的model是多的一方;

//  app/models/comment.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  post: DS.belongsTo(‘post’);
});

这种设置的方式与Java 的hibernate非常相似。

3,多对多

声明一对多关联使用DS.hasMany设置。比如下面的两个model。

//  app/models/post.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  tags: DS.hasMany(‘tag’);
});
//  app/model/tag.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  post: DS.hasMany(‘post’);
});

多对多的关系设置都是使用hasMany,但是并不需要“中间表”,这个与数据的多对多有点不同,如果是数据的多对多通常是通过中间表关联。

4,显示反转

Ember Data会尽力去发现两个model之间的关联关系,比如前面的一对多关系中,当comment发生变化的时候会自动更新到post,因为每一个comment只对应一个post,可以有comment确定到某个一个post。

然而,有时候同一个model中会有多个与此关联model。这时你可以在反向端用DS.hasMany的inverse选项指定其关联的model:

//  app/model/comment.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  onePost: DS.belongsTo(‘post’),
  twoPost: DS.belongsTo(‘post’),
  redPost: DS.belongsTo(‘post’),
  bluePost: DS.belongsTo(‘post’)
});

在一个model中同时与3个post关联了。

//  app/models/post.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  comments: hasMany(‘comment’, { inverse: ‘redPost’ });
});

当comment发生变化时自动更新到redPost这个model。

5,自反关系

1,一对多

当你想定义一个自反关系的model时(模型本身的一对一关系),你必须要显式使用inverse指定关联的model。如果没有逆向关系则把inverse值设置为null。

//  app/models/folder.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  children: DS.hasMany(‘folder’, { reverse: ‘parent’ });
  parent: DS.hasMany(‘folder’, { reverse: ‘children’ });
});

一个文件夹通常有父文件夹或者子文件夹。此时父文件夹和子文件夹与本身都是同一个类型的模型。此时你需要显式使用inverse属性指定,比如这段代码所示,“children……”这行代码意思是这个模型有一个属性children,并且这个属性也是一个folder,模型本身作为父文件夹。同理“parent……”这行代码的意思是这个模型有个属性parent,并且这个属性也是一个folder,模型本身是这个属性的子文件夹。比如下图结构:

这个有点像数据结构中的链表。你可以把children和parent想象成是一个指针。

如果仅有关联关系没有逆向关系直接把inverse设置为null。

//  app/models/folder.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  parent: DS.belongsTo(‘folder’, { inverse: null });
});
2,一对一
//  app/models/user.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  bestFriend: DS.belongsTo(‘folder’, { inverse: ‘bestFriend’ });
});

这个关系与数据库设置设计中双向一对一很类似。

6,嵌套数据

有些model可能会包含深层嵌套的数据对象,如果也是使用上述的关联关系定义那么将是个噩梦!对于这种情况最好是把数据定义成简单对象,虽然增加点冗余数据但是降低了层次。另外一种是把嵌套的数据定义成model的属性(也是增加冗余但是降低了嵌套层次)。

时间: 2024-12-13 01:05:01

Ember.js 入门指南——定义模型的相关文章

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

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

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 入门指南——控制器(controller)

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

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可以看做是一个缓存

Ember.js 入门指南--目录

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

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 入门指南——路由简介

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

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

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