最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I update all models in a collection - Backbone.js - Stack Overflow

programmeradmin7浏览0评论

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 because Die.value is not the same as Die.attributes.value. The latter is what gets changed when you call die.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
Add a ment  | 

2 Answers 2

Reset to default 5

Simply 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.

发布评论

评论列表(0)

  1. 暂无评论