Search code examples
javascriptbackbone.jsthis

Backbone this confusion


I have the following code:

var GoalPanelView = Backbone.View.extend({

    // Bind to the goal panel DOM element
    el: $("#sidebar-goals"),    

    // Initialize the collection
    initialize: function() {
        this.collection = Goals;
        this.collection.bind('add', this.appendItem);
    },

    // Create a new goal when a user presses enter in the enter goal input
    createOnEnter: function(e) {
        if (e.keyCode != 13) return;
        this.addItem();
        //Goals.create(this.newAttributes());           
    },

    // Add the goal item to the goal list
    addItem: function() {
        var goal = new Goal();
        goal.set(this.newAttributes());
        var goalsElem = this.el;
        this.collection.add(goal);
        $(this.el).children("#enter-goal").val('');
    },

    // Append DOM element to the parent el
    appendItem: function(item) {
        var goalView = new GoalView({
            model: item,
        });
        $(this.elem).append(goalView.render().el);
    }

});

My problem is inside of the appendItem function. When I use this inside of the appendItem function, I believe that it thinks that the this refers to the this.collection rather than the GoalPanelView. How would I get the this to refer to the GoalPanelView rather than the collection? I tried to pass another variable into the appendItem function which held the contents of this.elem, but it didn't seem to work.

One thing that worked was when I moved the appendItem function into the collection and changed the initialization to bind to this.collection.bind('add', appendItem); but I do not want to put the view stuff into the collection logic.


Solution

  • You can add a scope when binding an event handler, like so:

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

    The scope sets the value of this inside the handler. In you case, the current object.

    Edit: Javascript Garden has a great explaination why this.appendItem does not actually carry the scope of the function itself, it's just a function pointer, not a method pointer. One of the quirks of Javascript..

    Edit 2 Backbone Reference - Events / on