Backbone.js - Using new() in Model defaults - circ

2019-07-03 23:18发布

Taking the following Model:

MyModel= Backbone.Model.extend({
  defaults : {
    myNestedModel:undefined,
  },
  initialize: function() {
    this.set({myNestedModel: new MyNestedModel());
  }
});

It has a single property named 'myNestedModel' which has the following definition:

MyNestedModel= Backbone.Model.extend({
  defaults : {
    myModel:undefined,
  }
});

It too has a single Property name 'myModel'. Now if I create an instance of MyModel:

aModel = new MyModel();

The nested model will have been set in MyModel's initialize method. I then use JSON.stringify in a two step process:

// Use Backbone.js framework to get an object that we can use JSON.stringfy on
var modelAsJson = aModel.toJSON();

// Now actually do stringify 
var modelAsJsonString = JSON.stringify(modelAsJson);

This works fine and I get the JSON representation of MyModel and it's property of MyNestedModel. The problem occurs when I use defaults, for example:

MyModel= Backbone.Model.extend({
      defaults : {
        new MyNestedModel(),
      }
    });

This causes a problem with JSON.stringify since it doesn't support circular references. I assume the circular reference is being created because all instances of MyModel share the same instance of MyNestedModel. Whereas the initialize method creates a new nested model for each instance.

Questions:

  1. Is my understanding of defaults:{} being the 'cause' of the problem correct?
  2. From a question I posted recently I got the impression I should be using defaults for all properties. If that is the case, how should I be using defaults in the scenario presented in this post/question?
  3. Can someone clarify the use of defaults:{} with regards to when the value applies, when it's overridden and whether instances share the same default 'instances'?

标签: backbone.js
1条回答
▲ chillily
2楼-- · 2019-07-04 00:09

Defaults is used only for attributes inside your model ( the data in the model ), and whenever you create your model it takes the values from defaults and sets the attributes. e.g.

User = Backbone.Model.extend({
     defaults : {
         rating : 0
     }
})

User1 = new User({ name : 'jack', email : 'jack@gmail.com' });
User2 = new User({ name : 'john', email : 'john@gmail.com' });

User1.set({ rating : 2 });

Now your two models when called with toJSON will print

{
   rating: 2,
   name: 'jack',
   email: 'jack@gmail.com'
}
{
   rating: 0,
   name: 'john',
   email: 'john@gmail.com'
}

Since defaults is an object, every value you place there is evaluated immediately so :

defaults : {
    rating : defaultRating()
}

will call defaultRating() - not everytime when you initialize the model, but immediately ( in the extend method )

You should use defaults for models where you need some data to exist on the creating of the model ( e.g. new myModel() )

In your example you have the following mistakes :

1.set a value without a property

 defaults : {
      PROPERTY : new Model() 
 }

2.you don't need such an option for your defaults - you should place there only attributes ( data ) for the model

Defaults applies always as long as it is not replaced by a new defaults in an extended model e.g.

 var Model = Backbone.Model.extend({ defaults : { alpha : 'beta' } });
 var myModel = Model.extend({ defaults : { beta : 'gama' } });

now your myModel when initialized will have

 { beta : 'gama' } // alpha : 'beta' will not be set as value, because it is replaced
查看更多
登录 后发表回答