Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Ember defines the model


May 09, 2021 Ember.js Reference documents


Table of contents


A model is also a class that defines the properties and data behavior that are presented to the user. T he definition of the model is very simple and only needs to inherit DS. T he Model class is fine, or you can create it directly using the Ember CLI command. For example, a ember g model person the command model ember g model person

  1. // app/models/person.js
  2. import DS from 'ember-data';
  3. export default DS.Model.extend({
  4. });

This is an empty model that does not define any properties. With the model class, you can find method to find the data.

1, define the property

The model class person defined person not yet have any properties, so add a few properties to the class below.

  1. // app/models/person.js
  2. import DS from 'ember-data';
  3. export default DS.Model.extend({
  4. firstName: DS.attr(),
  5. lastName: DS.attr(),
  6. birthday: DS.attr()
  7. });

The above code defines three properties, but has not specified a type for the property, and the default string type. T hese property names are consistent with the data key on the servers you connect to. You can even define the calculated property in the model.

  1. // app/models/person.js
  2. import DS from 'ember-data';
  3. export default DS.Model.extend({
  4. firstName: DS.attr(),
  5. lastName: DS.attr(),
  6. birthday: DS.attr(),
  7. fullName: Ember.computed('firstName', 'lastName', function() {
  8. return `${this.get('firstName')} ${this.get('lastName')}`;
  9. })
  10. });

This code defines a calculated property, fullName

2, specifying the property type and default values

The model classes defined earlier are not specified property types and string which is obviously not string number boolean date These types I think I should know without my explanation.

Not only can you specify the property type, you can also specify the default value of the property, specified in the second argument of the attr() method. For example, the following code:

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

As described in code comments, setting default values includes specifying directly or using function return values.

3, define the association of the model

Ember's model also has a database-like association. I t's a lot simpler than the model of Ember, the replicated database, which includes one-to-one, one-to-many, many-to-many associations. This relationship is uniform with the database in the background.

1, one-on-one

Declares a one-to-one association using the DS.belongsTo setting. For example, the following two models.

  1. // app/models/user.js
  2. import DS from 'ember-data';
  3. export default DS.Model.extend({
  4. profile: DS.belongsTo(‘profile’);
  5. });
  1. // app/models/profile.js
  2. import DS from ember-data’;
  3. export default DS.Model.extend({
  4. user: DS.belongsTo(‘user’);
  5. });

2, one-to-many

Declares a one-to-many association using DS.belongsTo (used by multiple parties) and DS.hasMany (used by a smaller party) settings. For example, the following two models.

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

This model is one side. The following model is more than one side;

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

This setting is very similar to Java's hibernate.

3, many to many

Declare a one-to-many association using the DS.hasMany setting. For example, the following two models.

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

The many-to-many relationship settings all use DS.hasMany, but you don't need an "intermediate table", which is a little different from the many-to-many of the data, if the data is many-to-many, it's usually associated through an intermediate table.

4, explicit reversal

Ember Data tries to discover the association between two models, such as in the previous one-to-many comment post when the comment post because comment corresponds to only one post comment to post

However, sometimes there are multiple models associated with this in the same model. At this point, you can specify its associated model at the reverse end with DS.hasMany's inverse option:

  1. // app/model/comment.js
  2. import DS from 'ember-data';
  3. export default DS.Model.extend({
  4. onePost: DS.belongsTo(‘post’),
  5. twoPost: DS.belongsTo(‘post’),
  6. redPost: DS.belongsTo(‘post’),
  7. bluePost: DS.belongsTo(‘post’)
  8. });

Three posts are associated in one model at post same time.

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

The comment model is automatically redPost changes.

5, inverse relationship

1, one-to-many

When you want to define a model of inverse relationships (one-to-one relationships of the model itself), you must explicitly specify the associated model using inverse If there is no reverse relationship, inverse value null

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

A folder usually has a parent or child folder. A t this point, both the parent folder and the child folder are models of the same type as they are. A t this point you need inverse as shown in this code, "children..." this line of code means that the children is also folder parent folder. T he same "parent..." line of code means that the model has parent and this property is folder itself is a sub-folder of this property. For example, the structure of the following image:

Ember defines the model

This is a bit like a list in a data structure. You can children of parent and parent as a pointer.

Set inverse directly to null if only the association does not have null

  1. // app/models/folder.js
  2. import DS from ember-data’;
  3. export default DS.Model.extend({
  4. parent: DS.belongsTo(‘folder’, { inverse: null });
  5. });

2, one-on-one

  1. // app/models/user.js
  2. import DS from ember-data’;
  3. export default DS.Model.extend({
  4. bestFriend: DS.belongsTo(‘folder’, { inverse: bestFriend });
  5. });v

This relationship is similar to two-way one-to-one in database setup design.

6, nested data

Some models may contain deeply nested data objects, which can be a nightmare if they are also defined using the associations above! I n this case, it is best to define the data as a simple object, although adding some redundant data reduces the hierarchy. T he other is to define nested data as the properties of the model (also increasing redundancy but reducing the level of nesting).
The full code of the blog post is placed in Github (the blog post has been modified several times, and the code on the blog post may be different from the github code, but the impact is small!). I f you think the blog post is a bit useful to you, please give me a star on the star project. Yours is definitely the biggest motivation for me!!