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

发布于 2024-12-14 08:42:52 字数 848 浏览 0 评论 0原文

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

以下代码块位于“应用程序"部分,并迭代 Todos集合。我的问题是 addOne 函数作为对 Todos 集合的引用传递,但该函数具有对 this 的引用,这不是与 Todos 集合对象调用该函数时 this 所引用的内容相同。

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

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

This question is about the "Todos" Backbone.js sample, which is at:
http://documentcloud.github.com/backbone/docs/todos.html

The following block of code is in "The Application" section, and iterates through the Todos collection. My issue is that the addOne function is passed as a reference to the Todos collection, but that function has a reference to this, which is not the same as what this would refer to when the function is called by the Todos collection object.

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

Why does the function execute correctly when the caller is not calling it in the context of the instantiated AppView object?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你好,陌生人 2024-12-21 08:42:52

我刚刚解决了。我想到 this 默认引用 window 对象,并且由于 jQuery 全局注册了 $,即使使用以下函数调用,该函数也能工作没有上下文对象。

I just worked it out. It occurred to me that this refers to the window object by default and seeing as jQuery registers $ globally, the function will work even if called with no context object.

烏雲後面有陽光 2024-12-21 08:42:52

“如果页面上包含 jQuery 或 Zepto,则每个视图都有一个 $ 函数,用于运行视图元素范围内的查询。”

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

上下文是addOne 和 addAll 具有相同的(视图),并且通过绑定调用中的第三个参数来实现。

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

"If jQuery or Zepto is included on the page, each view has a $ function that runs queries scoped within the view's element."

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

Context is the same (view) for both addOne and addAll and it is achieved with the third parameter in bind calls.

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

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

--edit

Hmm.. then again do those binds ensure the context when addOne is ran with each?

addAll: function() {
  Todos.each(this.addOne);
},
墟烟 2024-12-21 08:42:52

对于未来的 Google 员工,此问题已在 GitHub 上提交,并修复已应用,但它并没有真正解决问题。

我认为解决这个问题的最好方法是让 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 _.each 函数有第三个选项(第二个,在我们的例子中)参数指定上下文迭代。

For future Googlers, this issue was submitted on GitHub and a fix was applied, but it doesn't really address the issue.

I think the best way to solve this problem is have the addAll function bind its own this to the .each iteration, i.e.

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
},

We can do this because Underscore.js's _.each function has an option third (second, in our case) parameter to specify the context for the iteration.

伴我老 2024-12-21 08:42:52

看一下 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 的第三个(可选)参数是调用回调的上下文。它记录在此处。 Backbone 中的实现位于此处

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

Take a look at the initialize method:

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

That third (optional) argument to bind is the context with which the callback gets called. It's documented here. The implementation in Backbone is here:

callback[0].apply(callback[1] || this, args);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文