2012-03-26 91 views
5

我有以下代码:骨干这种混乱

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); 
    } 

}); 

我的问题是appendItem函数内。当我在appendItem函数中使用this时,我认为它认为this是指this.collection而不是GoalPanelView。我如何获得this来引用GoalPanelView而不是collection?我尝试将另一个变量传入appendItem函数,该函数保存this.elem的内容,但它似乎不起作用。该工作

的一件事是,当我提出的appendItem功能为collection,改变了初始化绑定到this.collection.bind('add', appendItem);,但我不想把view东西到collection逻辑。

+2

另一种方法是将'_.bindAll(this)'放入您的初始化函数中。这可以确保在对象中调用的任何函数都将与“this”的值一起适用于对象本身。如果你正在写很多回调,这很有用。 – rybosome 2012-07-30 06:02:32

回答

6

绑定的事件处理程序的时候,像这样您可以添加范围:

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

范围设置的this的处理程序中的价值。在你的情况下,当前的对象。

编辑:Javascript Garden有一个伟大的解释,为什么this.appendItem并不实际执行函数本身的范围,它只是一个函数指针,而不是一个方法指针。其中的JavaScript怪癖的..

编辑2Backbone Reference - Events/on

0

您还可以使用下划线的_.bindAll功能在您的initialize方法:

initialize: function() { 
    _.bindAll(this); 
    this.collection = Goals; 
    this.collection.bind('add', this.appendItem); 
} 

现在就GoalPanelView任何方法的调用(如appendItem)的范围将使得对this的引用指的是GoalPanelView实例。

您也可以通过在方法的名字作为一个字符串列表,如果你不想范围内的所有的GoalPanelView

见这里的方法:http://underscorejs.org/#bindAll

2

只是为了更新(如骨干0.9。 2),这样做的正确方法是:

initialize: function() { 
    this.collection.on("add", this.appendItem, this); 
    ... 
} 


根据你的使用情况,您可以将我也想考虑:

initialize: function() { 
    this.listenTo(this.collection, "add", this.appendItem); 
    ... 
} 
+0

这是正确的做法 – 2013-02-25 08:15:47

+1

实际上,使用“this.listenTo”会更好,因此在调用remove时会自动解除绑定事件。这样你可以防止内存泄漏。 – 2014-03-01 21:53:33