0

I am using RequireJS and Backbone and listening to a collection's add event using listenTo. I cannot figure out how to reference this as the instance of the view I am in, in this case GroupView.

define([
    'underscore',
    'backbone',
    'handlebars',
    ...
    ...
    ], function(_,Backbone,Handlebars,...){
    ...
    ...
    var GroupsView = Backbone.View.extend({
        el: "#current-item",

        collection: Groups,
        model: Group,

        groupTemplate: Handlebars.compile(GroupTemplate),

        events: {
            "click #add-group"              : "addGroupClicked",
        },

        initialize: function(){
            this.listenTo(Groups,'add',this.addGroup,this);
        },

        addGroup: function(group){
            //I want a reference to this instance of GroupsView here.
            //if I use this... it references
            //Uncaught TypeError: Object [object global] has no method 'groupTemplate' 
            console.log(this.groupTemplate);
            //Uncaught TypeError: Object [object global] has no method 'redrawGroups' 
-->         console.log(this.redrawGroups);
        },

        redrawGroups: function(){

        },
    ...
    ...
Johnston
  • 20,196
  • 18
  • 72
  • 121

1 Answers1

2

You have:

 this.listenTo(Groups,'add',this.addGroup,this);

With Backbone's on you can provide a 4th argument, as you have done, to set the context. However, that doesn't work with listenTo; it only takes three arguments (this is because listenTo always sets the context to the listented-to object).

You should be able to get around this by creating a bound addGroup like so:

 this.listenTo(Groups,'add',_(this.addGroup).bind(this));

Alternatively you could simply bind the method to your class with:

_(this).bindAll('addGroup');

which would then let you do just:

 this.listenTo(Groups,'add',this.addGroup);
machineghost
  • 33,529
  • 30
  • 159
  • 234
  • The `bindAll` solution did work for me. However the first example with just `bind` did not seem to work for me. I don't understand why it wouldn't work. Thank you sir! – Johnston Nov 26 '13 at 23:43
  • Odd, they should be equivalent ... glad you got it working though. – machineghost Nov 26 '13 at 23:44
  • Also I did not know you could do `_(this).bindAll('addGroup')`. I thought it had to be `_.bindAll(this,'addGroup')`. – Johnston Nov 26 '13 at 23:47
  • @user974407: ["You can use Underscore in either an object-oriented or a functional style, depending on your preference."](http://underscorejs.org/#chaining). I use the `_(x).m()` version almost exclusively because I find it easier to read. The `_(f).bind()` version should work the same but it will only `addGroup` a bound function for that single `this.listenTo` call. – mu is too short Nov 27 '13 at 00:04
  • @muistooshort: So it would have that binding if called from `listenTo`. But if we called `addGroup` from elsewhere (not `listenTo`) it would not have that binding? – Johnston Nov 27 '13 at 03:54
  • @user974407: Right, [`_.bind`](http://underscorejs.org/#bind) *returns* a new function bound to the specified `this`, it doesn't modify the function in-place. I have some discussion on this over here: http://stackoverflow.com/a/7087753/479863 – mu is too short Nov 27 '13 at 04:28