英文原文:http://emberjs.com/guides/models/defining-models/

A model is a class that defines the properties and behavior of the data that you present to the user. Anything that the user expects to see if they leave your app and come back later (or if they refresh the page) should be represented by a model.

模型是一个定义了需要呈现给用户的数据的属性和行为的类。任何用户往返于应用(或者刷新页面)能看到的内容都需要使用模型来表示。

For every model in your application, create a subclass of DS.Model:

应用中所有的模型,都继承与DS.Model

  1. App.Person = DS.Model.extend();

After you have defined a model class, you can start finding and creating records of that type. When interacting with the store, you will need to specify a record’s type using the model name. For example, the store’s find() method expects a string as the first argument to tell it what type of record to find:

在定义了一个模型类之后,就可以开始查询或者创建一个属于这个类型的记录。当与仓库进行交互时,需要使用模型的名称来指定记录的类型。例如,仓库的find()方法需要一个字符串类型的值作为第一个参数,用于指定需要查询的记录类型:

  1. store.find('person', 1);

The table below shows how model names map to model classes.

下表说明了模型名称是如何映射到模型的类的。

模型名称 模型类
photo App.Photo
adminUserProfile App.AdminUserProfile

Defining Attributes

定义属性

You can specify which attributes a model has by using DS.attr.

模型的属性是通过DS.attr来进行声明的。

  1. var attr = DS.attr;
  2. App.Person = DS.Model.extend({
  3. firstName: attr(),
  4. lastName: attr(),
  5. birthday: attr()
  6. });

Attributes are used when turning the JSON payload returned from your server into a record, and when serializing a record to save back to the server after it has been modified.

属性主要由两个作用,其一是用于转换从服务器返回的JSON数据到记录;其二是序列化一个被修改的记录,将其变动保存到服务器端。

You can use attributes just like any other property, including as part of a computed property. Frequently, you will want to define computed properties that combine or transform primitive attributes.

属性(Attribute)可以跟其他属性(Property)一样看待,包括计算属性。应用中经常需要使用计算属性来联合或者转换一个原生属性(Attribute)的值。

  1. var attr = DS.attr;
  2. App.Person = DS.Model.extend({
  3. firstName: attr(),
  4. lastName: attr(),
  5. fullName: function() {
  6. return this.get('firstName') + ' ' + this.get('lastName');
  7. }.property('firstName', 'lastName')
  8. });

For more about adding computed properties to your classes, see Computed Properties.

关于如何为类添加计算属性,可以参看计算属性

If you don’t specify the type of the attribute, it will be whatever was provided by the server. You can make sure that an attribute is always coerced into a particular type by passing a type option to attr:

如果没有指定属性的类型,属性类型与服务器端返回的保持一致。可以通过attr设定属性的类型type,来确保将服务器返回的数据强制转换为指定的类型。

  1. App.Person = DS.Model.extend({
  2. birthday: DS.attr('date')
  3. });

The default adapter supports attribute types of string, number, boolean, and date. Custom adapters may offer additional attribute types, and new types can be registered as transforms. See the documentation section on the REST Adapter.

默认情况下,REST 适配器支持的属性类型有string, number, booleandate。 传统的适配器会提供额外的属性类型,并支持你注册自定义的属性类型。 详情请查看documentation section on the REST Adapter

Options

选项

DS.attr takes an optional hash as a second parameter, current options are:

DS.attr第二个参数是一个可选的哈希对象,当前支持的选项是:

  • defaultValue: Pass a string or a function to be called to set the

    1. attribute to a default value if none is supplied.
  • defaultValue:传入一个字符串或者将被调用来设置属性的初始值的函数。

    Example

    示例

    1. var attr = DS.attr;
    2. App.User = DS.Model.extend({
    3. username: attr('string'),
    4. email: attr('string'),
    5. verified: attr('boolean', {defaultValue: false}),
    6. createdAt: DS.attr('string', {
    7. defaultValue: function() { return new Date(); }
    8. })
    9. });

定义关联模型(Defining Relationships)

Ember Data includes several built-in relationship types to help you define how your models relate to each other.

Ember Data 包括了几个内置的关联类型,以帮助你确定你的模型如何相互关联的。

一对一(One-to-One)

To declare a one-to-one relationship between two models, use DS.belongsTo:

使用DS.belongsTo在两个模型间声明一对一的关系。

  1. App.User = DS.Model.extend({
  2. profile: DS.belongsTo('profile')
  3. });
  4. App.Profile = DS.Model.extend({
  5. user: DS.belongsTo('user')
  6. });

一对多(One-to-Many)

To declare a one-to-many relationship between two models, use DS.belongsTo in combination with DS.hasMany, like this:

使用DS.belongsTo结合DS.hasMany来声明两个模型间的一对多关系,示例如下:

  1. App.Post = DS.Model.extend({
  2. comments: DS.hasMany('comment')
  3. });
  4. App.Comment = DS.Model.extend({
  5. post: DS.belongsTo('post')
  6. });

多对多(Many-to-Many)

To declare a many-to-many relationship between two models, use DS.hasMany:

使用DS.hasMany来声明两个模型间的多对多关系。

  1. App.Post = DS.Model.extend({
  2. tags: DS.hasMany('tag')
  3. });
  4. App.Tag = DS.Model.extend({
  5. posts: DS.hasMany('post')
  6. });

Explicit Inverses

显式反转

Ember Data will do its best to discover which relationships map to one another. In the one-to-many code above, for example, Ember Data can figure out that changing the comments relationship should update the post relationship on the inverse because post is the only relationship to that model.

Ember Data会尽最大努力去自动发现关联关系的映射关系。在上例的一对多的情况下,修改了comments会自动更新post,应为这是唯一的一个关联模型。

However, sometimes you may have multiple belongsTo/hasManys for the same type. You can specify which property on the related model is the inverse using DS.hasMany‘s inverse option:

但是,有时候对同一个类型有多个belongsTo/hasMany关联关系。这时可以通过指定在反向端使用DS.hasManyinverse选项来指定其关联的模型:

  1. var belongsTo = DS.belongsTo,
  2. hasMany = DS.hasMany;
  3. App.Comment = DS.Model.extend({
  4. onePost: belongsTo("post"),
  5. twoPost: belongsTo("post"),
  6. redPost: belongsTo("post"),
  7. bluePost: belongsTo("post")
  8. });
  9. App.Post = DS.Model.extend({
  10. comments: hasMany('comment', {
  11. inverse: 'redPost'
  12. })
  13. });

You can also specify an inverse on a belongsTo, which works how you’d expect.

当然也可以在belongsTo一侧指定,它将按照预期那样工作。