I am setting the value
attribute of all models in a collection (in an _.each
loop). After the loop is finished, each value
attribute is unchanged. I believe this is because the _.each
loop is creating a new instance variable for each model. Is there a standard way to update models of a collection that I am not following?
The code which should force the dice into a straight (1,2,3,4,5,6). rollableDice
refers to a Backbone collection of Backbone models which have a value
attribute. This is a method on a container model:
makeStraight: function() {
console.log('making straight');
console.log(_(this.rollableDice.models).pluck('value'));
var counter = 1;
_(this.rollableDice.models).each(function(die) {
console.log(die.get('value'));
die.set('value', counter);
console.log(die.get('value'));
counter++;
});
console.log(_(this.rollableDice.models).pluck('value'));
},
This is the output that I see on the console:
making straight
[1, 1, 3, 5, 2, 1]
undefined
1
undefined
2
undefined
3
undefined
4
undefined
5
undefined
6
[1, 1, 3, 5, 2, 1]
//EDIT This is the console output that I expect to see:
making straight
[1, 1, 3, 5, 2, 1]
1
1
1
2
3
3
5
4
2
5
1
6
[1, 2, 3, 4, 5, 6]
//EDIT I'm going to show the model code in response to @numbers1311407's response. I should not be using a model method to store and access attributes. Instead, I should use the get/set methods or defaults method () even while inside the model. This is what not to do:
var Die = Backbone.Model.extend({
initialize: function() {
_.bindAll(this, 'roll')
},
value: 1,
roll: function() {
this.value = _.random(1,6);
},
});
I am setting the value
attribute of all models in a collection (in an _.each
loop). After the loop is finished, each value
attribute is unchanged. I believe this is because the _.each
loop is creating a new instance variable for each model. Is there a standard way to update models of a collection that I am not following?
The code which should force the dice into a straight (1,2,3,4,5,6). rollableDice
refers to a Backbone collection of Backbone models which have a value
attribute. This is a method on a container model:
makeStraight: function() {
console.log('making straight');
console.log(_(this.rollableDice.models).pluck('value'));
var counter = 1;
_(this.rollableDice.models).each(function(die) {
console.log(die.get('value'));
die.set('value', counter);
console.log(die.get('value'));
counter++;
});
console.log(_(this.rollableDice.models).pluck('value'));
},
This is the output that I see on the console:
making straight
[1, 1, 3, 5, 2, 1]
undefined
1
undefined
2
undefined
3
undefined
4
undefined
5
undefined
6
[1, 1, 3, 5, 2, 1]
//EDIT This is the console output that I expect to see:
making straight
[1, 1, 3, 5, 2, 1]
1
1
1
2
3
3
5
4
2
5
1
6
[1, 2, 3, 4, 5, 6]
//EDIT I'm going to show the model code in response to @numbers1311407's response. I should not be using a model method to store and access attributes. Instead, I should use the get/set methods or defaults method (http://backbonejs/#Model-defaults) even while inside the model. This is what not to do:
var Die = Backbone.Model.extend({
initialize: function() {
_.bindAll(this, 'roll')
},
value: 1,
roll: function() {
this.value = _.random(1,6);
},
});
Share
Improve this question
edited May 6, 2013 at 18:24
Nathan
asked May 6, 2013 at 17:41
NathanNathan
1,7621 gold badge20 silver badges30 bronze badges
2
-
Wait, are you using the above model code with the above
makeStraight
method? I ask becauseDie.value
is not the same asDie.attributes.value
. The latter is what gets changed when you calldie.set('value',1)
. – jackwanders Commented May 6, 2013 at 18:40 - Yes, that is what I was doing. @numbers1311407's response below made that clear. Now I'm using model attributes appropriately. – Nathan Commented May 7, 2013 at 14:26
2 Answers
Reset to default 5Simply use the collection.each
method.
myCollection.each(function(model) {
// do stuff
});
Checkout Underscore.js method extend by Backbone.Collection: http://backbonejs/#Collection-Underscore-Methods
You're already updating all the models in the collection, but you're deceived into thinking you aren't by accessing the value incorrectly when logging.
console.log(_(this.rollableDice.models).pluck('value'));
This line does not get
the value of the model, it's logging a value
property on the model instance itself, suggesting that you initialized the models improperly.
pluck
is a collection method (as is each
, as @SimonBoudrias points out). You should use the designated methods when working with collections where possible, rather than wrapping them with underscore yourself.
Using Collection#pluck
, your first and last console logs would look like this:
console.log(this.rollableDice.pluck("value"));
Using that, you'll see something closer to what you expect, but as pointed out, the initial log will still be an array of undefined
, as value
appears to be a property of the model instance, not a proper Model attribute.