Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving index position of item added to Backbone.js Collection

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?

like image 358
Jack Avatar asked Apr 15 '12 10:04

Jack


People also ask

How do you find model index?

To obtain a model index that refers to an existing item in a model, call QAbstractItemModel::index() with the required row and column values, and the model index of the parent.

What is collections in Backbone JS?

Collections are ordered sets of Models. We just need to extend the backbone's collection class to create our own collection. Any event that is triggered on a model in a collection will also be triggered on the collection directly.

How does Backbone js work?

Backbone. js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.

Why use Backbone js?

BackboneJS allows developing of applications and the frontend in a much easier way by using JavaScript functions. BackboneJS provides various building blocks such as models, views, events, routers and collections for assembling the client side web applications.


2 Answers

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);
like image 78
Derick Bailey Avatar answered Sep 30 '22 07:09

Derick Bailey


UPDATED

If you want to know the "index" of an element in a collection with underscore you can use indexOf.

Could you add a bigger sample of your code maybe in a fiddle so I can understand better what you want to do? Because for example if the elements in the collection are not primitive types (no ints or Strings but javascript objects) indexOf can present problems because objects with the same value that are different references wouldn't be considered equal by indexOf.

UPDATED 2

You could try doing this:

var cids = this.collection.map(function(elem){ return elem.cid; });
var index = _(cids).indexOf(myModel.cid);
like image 44
txominpelu Avatar answered Sep 30 '22 06:09

txominpelu