I really like Backbone, but I am having the hardest time doing what would seem to be simple things. I appreciate any help with the following example.
I have a model,
When you define 'tags' under 'defaults', you create a new Array and set that to the default value for that class. Then, when you create a new instance, it has the same Array reference, which still has the things you pushed into it.
Rather than setting a default value for tags, you should be able to just set it to []
before you use it the first time:
window.criteria = new Criteria()
window.criteria.set({'tags', []}) //you can use new Array() if you want
window.criteria.get('tags').push(5)
window.criteria = new Criteria()
console.log(window.criteria.get('tags')) //should be undefined
window.criteria.set({'tags', []})
Thom Blake is right about why it's keeping the same values for the array. one option for solving this is to set the default value in the initializer
var Criteria = Backbone.Model.extend({
defaults: {
"status": "Normal",
"priority": "Normal"
},
initialize: function(){
if( !this.get('tags') ){
this.set({tags: new Array()});
}
}
});
"defaults" can also be a function.
var Criteria = Backbone.Model.extend({
defaults: function () {
return {
"status": "Normal",
"priority": "Normal",
"tags": new Array()
}
}
});
This would create a new array when a new Criteria is instantiated. See: http://backbonejs.org/#Model-defaults
To be clear, the last option provided by Maksym H. will not solve the problem. The defaults property is provided assuming all of the values set are immutable. An array, however, is mutable, meaning its value can be changed (e.g. tags[0] = "hello" can be changed with tags[0] = "hi there").
By using btford's answer, you are forcing a new instance of any mutable object/property to be created on every new instance of the model, so it is never shared, because the object is created with a function scoped variable.
Similarly, Derick Bailey's answer is correct, it just uses the initialize method instead of the defaults method.