Backbone.js“Todos”示例 - 不确定为什么某个代码片段有效

时间:2011-11-08 19:26:35

标签: javascript backbone.js

这个问题是关于“Todos”Backbone.js样本,它位于: http://documentcloud.github.com/backbone/docs/todos.html

The following block of code位于“The Application”部分,并遍历Todos集合。我的问题是addOne函数作为对Todos集合的引用传递,但该函数引用了this,这与this不同将引用Todos集合对象调用函数的时间。

addOne: function(todo) {
    var view = new TodoView({model: todo});
    this.$("#todo-list").append(view.render().el);
},
addAll: function() {
    Todos.each(this.addOne);
},

当调用者未在实例化的AppView对象的上下文中调用函数时,为什么函数会正确执行?

4 个答案:

答案 0 :(得分:5)

我刚刚解决了。我突然想到this默认引用window对象并且看到jQuery全局注册$,即使没有上下文对象调用,该函数也会起作用。

答案 1 :(得分:1)

“如果页面上包含jQuery或Zepto,则每个视图都有一个$函数,它运行在视图元素中作用域的查询。”

http://documentcloud.github.com/backbone/#View-dollar

上下文对于addOne和addAll都是相同的(视图),它是通过bind调用中的第三个参数实现的。

Todos.bind('add',   this.addOne, this);
Todos.bind('reset', this.addAll, this);

http://documentcloud.github.com/backbone/#Events-bind

- 修改

嗯......然后再次确定这些绑定是否确保了每个运行addOne时的上下文?

addAll: function() {
  Todos.each(this.addOne);
},

答案 2 :(得分:1)

对于未来的Google员工,此问题在GitHub上为submitted,并且已应用fix,但它并未真正解决此问题。

我认为解决此问题的最佳方法是让addAll函数将自己的this绑定到.each次迭代,即

addOne: function(todo) {
  var view = new TodoView({model: todo});
  this.$("#todo-list").append(view.render().el);
},

addAll: function() {
  Todos.each(this.addOne, this); // notice the second parameter
},

我们可以这样做,因为Underscore.js's _.each函数有一个选项第三个(在我们的例子中是第二个)参数来指定迭代的上下文。

答案 3 :(得分:0)

查看initialize方法:

initialize: function() {
  this.input    = this.$("#new-todo");

  Todos.bind('add',   this.addOne, this);
  Todos.bind('reset', this.addAll, this);
  Todos.bind('all',   this.render, this);

  Todos.fetch();
}

bind的第三个(可选)参数是调用回调的上下文。它记录了here。 Backbone中的实现是here

callback[0].apply(callback[1] || this, args);