Retrieving index position of item added to Backbone.js Collection

Jack picture Jack · Apr 15, 2012 · Viewed 11.4k times · Source

If I add an item to a Collection how can I find the position at which it was added? The Underscore.js documentation for add suggests the only way to achieve this is by binding to the add event.

Is there any other way? If not, then how can I reteive the index from my callback? I tried providing a callback of:

foo:function(model, options) {
  console.log("foo: " + options.index);
},

but options.index is undefined. I bind to the event with this code:

this.collection.bind('add', this.foo);

and add an item with this code:

this.collection.add(myNewItem);

The model in the collection is:

MyModel = Backbone.Model.extend({
defaults : {
   key:undefined,
   myObj:undefined,
},

The collection is:

MyModel List = Backbone.Collection.extend({
      model: MyModel,

initialize: function() {
   this.comparator = function(aModel) {
   return aModel.get('key'); 
  };
 }});

I am adding the model to the collection with:

 var key = "always_the_same";
var mm = new MyModel({key:key});
this.collection.add(mm);
var index = this.collection.sortedIndex(mm , this.collection.comparator));

Update

The problem is (I think), the comparator function is used for indexOf and sortedIndexOf, therefore two objects with the same key are effectively the same object as far as the comparator function is concerned.

I had hoped* that the CID would be used to ensure the object was actually the object I'm looking for in the already sorted collection. However it seems not. I guess one possible solution is to change my comparator function to include the CID:

initialize: function() {
        this.comparator = function(aModel) {
          return aModel.get('key') + aModel.cid; 
        };
      },

The models remain sorted according to their key value, but the following code returns the correct index position:

this.collection.sortedIndex(myModel, this.collection.comparator);

Feels hacky :( Can any one offer their opinion on this?

Answer

Derick Bailey picture Derick Bailey · Apr 15, 2012

If you're dealing with a simple scenario of adding a model to a collection with the add method, then you only need to call the indexOf method with that model, after adding it.

var myModel = new MyModel({some: "data"});

var myCollection = new MyCollection();
myCollection.add(myModel);

var index = myCollection.indexOf(myModel);