7

警告:我是骨干新手。

我正在迭代我的集合中的所有模型并渲染它们。然而,很简单,我想确保我很好地理解它是如何工作的。这就是我所拥有的 -

模型:

File = Backbone.Model.extend({});

收藏

Folder = Backbone.Collection.extend({ model: File });

模型视图

FileView = Backbone.View.extend({
    initialize: function() {
       _.bindAll(this, 'render');
       this.render();
    },
    render: function() {
        this.template = _.template(document.getElementById("fileTemplate").innerHTML);
        this.$el.html(this.template({ fileName: this.model.get("FileName") }));
    }   
})

集合视图

FolderView = Backbone.View.extend({    
    initialize: function () {
        _.bindAll(this, 'render');
        this.render();
    },
    render: function () {
        _(this.collection.models).each(function(file) {
            var fileView = new FileView({ model: file});
            this.$el.append(fileView.el);            
        },this); <--???
    }
});

这工作得很好。我的问题是关于我的 FolderView 中的 _.each 。为什么我必须将这个传回我的每个循环?如果我不通过this,它指的是我的窗口对象而不是我的集合。我知道有必要通过它,我只是不知道为什么。

4

3 回答 3

11

_.each(list, iterator, [context]) Alias: forEach

迭代一个元素列表,依次将每个元素生成一个迭代器函数。如果传递了一个,则迭代器绑定到上下文对象。迭代器的每次调用都使用三个参数调用:(元素、索引、列表)。如果 list 是 JavaScript 对象,迭代器的参数将是 (value, key, list)。如果存在,则委托给本机 forEach 函数。

下划线文档#each

默认上下文是窗口对象。通过设置this为上下文,您可以this将函数映射到this调用函数的位置。

有关此主题的参考,请参阅以下内容:

于 2013-08-15T14:07:56.370 回答
3

为了解释你需要首先意识到在 JavaScript 中只有一个函数会创建一个新的作用域(没错,循环并没有真正创建一个新的作用域),并且与其他一些语言不同,该作用域的上下文是可变的,这取决于它的方式在该范围内称为this可能指的是不同的事物。

因此,出现的一个常见问题是您可能有一个内部函数和外部函数,并且在内部函数中您想要引用外部函数的范围,但内部函数已经更改了范围,因此this不再引用外部函数。

为了处理这个问题,我们需要确保保存外部函数的上下文(查看以下内容以获得更详细的说明)。

您可能在 JavaScript 中看到的一种常见模式是将上下文 ( this) 分配给一个变量,然后在函数中使用它。

例如,您的渲染函数在技术上可能已被重写为以下内容

 render: function () {
       var self = this; 
        _(this.collection.models).each(function(file) {
            var fileView = new FileView({ model: file});
            self.$el.append(fileView.el);            
        });
    }

现在我们提供了对的基本了解,this我们context可以转向Underscore.js 中的函数, _.each_.each像underscore.js的大多数函数一样采用可选的第三个参数,它指的是 underscore.js 然后使用的上下文,所以您可以方便地参考该上下文。

Underscore.js 还提供了一个实用函数 bind来将上下文绑定到函数。

于 2013-08-15T14:09:38.423 回答
0

最初的问题是,“为什么我必须在 each(fn, this) 调用中覆盖“this”?

您正在为第一个参数创建一个匿名函数。默认情况下,函数内的“this”指的是持有对调用函数的引用的对象。您的匿名函数是针对根上下文对象创建的,该对象是浏览器中的窗口。当您不为第二个参数提供对象时,这就是您所观察到的。

each() 能够确定您是否传递了不同的对象以在函数中充当“this”。each() 然后可以使用 Object.bind() 或 Object.call(),两者都使用传递给它们的第一个参数来覆盖“this”。

将“this”作为第二个参数传递给 each() 会导致外部函数的上下文对象在内部函数中用作“this”。

于 2014-04-16T15:22:24.813 回答