2

I'm not sure if I'm doing this right, first time playing with Backbone.js.

I have two views with two models and I want to use the event aggregator method to fire events between the two.

The aggregator declaration:

Backbone.View.prototype.eventAggregator = _.extend({}, Backbone.Events);

So in one view I have a line like this that will fire the removeRow method.

this.eventAggregator.trigger("removeRow", this.row);

In another view

MyView = Backbone.View.extend({
    initialize: function() {
      this.eventAggregator.bind("removeRow", this.removeRow);
      this.model.get("rows").each(function(row) {
        // Do stuff
      }); 
    },
    removeRow: function(row) {
       // row is passed in fine
       // this.model is undefined
       this.model.get("rows").remove(row);
    }
});

I think I understand why this.model is undefined, but what can I do to maintain a reference so that I can use this.model in the callback? I thought about passing the model to the first view and then passing it back in the trigger call, but that seems to make the entire point of an event aggregator pointless. If I have the model I can just call the .remove method directly and have lost the benefit of my first view being unaware of the model. Any suggestions?

Community
  • 1
  • 1
Brandon
  • 68,708
  • 30
  • 194
  • 223

3 Answers3

3

I think you have binding problem.

You have two ways to assure that this will be the View instance:

1. Using bindAll

In your View.initialize() you can add this line:

_.bindAll( this, "removeRow" )

Interesting post of @DerickBailey about this matter

2. Using the optional third argument in your bind declaration

Like this:

this.eventAggregator.bind("removeRow", this.removeRow, this);

Backbone documentation about this matter

fguillen
  • 36,125
  • 23
  • 149
  • 210
2

Supply your View object as third parameter of the bind method:

this.eventAggregator.bind("removeRow", this.removeRow, this);

The third parameter is the context of calling your callback. See the docs.

Also, you can use .on() instead of .bind() which is shorter...

Dmitry Pashkevich
  • 13,431
  • 9
  • 55
  • 73
2

You need to bind this so scope isn't lost. The blog link on the other answer uses underscore's bindAll

initialize: function() {
  _.bindAll(this, 'removeRow');
  this.eventAggregator.bind("removeRow", this.removeRow);
  this.model.get("rows").each(function(row) {
    // Do stuff
  }); 
},
JaredMcAteer
  • 21,688
  • 5
  • 49
  • 65