0

I'm creating a collection without using fectch(), but with JSON data already available.

this.displays = new Displays(jQuery.parseJSON($('#temp_json').html()));

I need for each model of that collections to have a 'position' value setup, which should be the position of this model in this collection.

What I'm trying to do is to catch an event, where in the initial load each model is constructed from the JSON and added to the collection.

I'll then make something like:

theModel.set('position', this.length);

Unfortunately I can't find that event I should bind my collection to. Also this collections's models contains other collection (...) where same should be done.

This might seems weird but I have to do this as later on in my view I'll peform things like:

var prototypeNames = [this.model.get('display').get('position'), this.model.get('position')];

Hope this is clear enough. Thanks!

LEM01
  • 871
  • 3
  • 15
  • 23

3 Answers3

1

The Collection.add-function fires a add-event, which you can listen to with the on-function. The event passes the added model AND an options object, which contains some useful attributes (like the index where the model was added), as parameters. (documentation here)

So you'll do something like this:

collection.on('add', function(model, options) {
  model.set('position', options.index); 
});

if you want to find out more about the parameters the add-event passes, just log them, because the existing documentation is scant at best.

collection.on('add', function(model, options) {
  console.log(options); 
});

Hope this helps!

jakee
  • 18,486
  • 3
  • 37
  • 42
  • If I'm not mistaken this event is not triggered when constructing the collection if it contains several items. So onLoad this is not triggered which is what I needed. – LEM01 Aug 02 '12 at 11:42
0

Solution that worked for me:

I used backboneRelational, which is awesome when working with actual model relationships. I'm listening to "relational:add" which is triggered for each item of the collection when constructing it.

I then set some values on my item and trigger a new event 'postAdd' that can be listened to from my view.

window.Displays  = Backbone.Collection.extend({
    model: Display,
    initialize: function(data, options){
        this.on("relational:add", function(relModel){
            relModel.set('pos',this.indexOf(relModel));
            this.trigger('postAdd', relModel);
        }, this);
    },

});
LEM01
  • 871
  • 3
  • 15
  • 23
0

You can override the default 'add' implementation of the collection to trigger a custom event which won't be silenced by Backbone.

var MyCollection = Backbone.Collection.extend({

  // Override the default 'add' implementation...
  add: function( models, options ) {

    // Call the default implementation first...
    Backbone.Collection.prototype.add.apply( this, arguments );

    // Fire our custom events on the models...
    while (model = models.shift()) {
      model.trigger('customAdd', model, this, options);
    }

    return this;
  }

});

You can now listen to the 'customAdd' event triggered on the model. This one will always be triggered, event when silent = true.

As a consequence, when an item is added an with {silent: false} two events will be triggered: 'add' and 'customAdd'.

I've used this technique to fire an event when a new collection has initially loaded and all models are created. Since the initialize method will be called before the models are created, I needed to override the 'reset' function to trigger my code to execute when the models were created.

toon.ketels
  • 201
  • 2
  • 4