Binding and _.bindAll in backbone.js

Binding and _.bindAll in backbone.js

本文关键字:backbone js in bindAll and Binding      更新时间:2023-09-26

我对backbone.js中_bind.All的绑定和用途感到困惑。下面是一个工作代码,它创建了一个模态视图#modal,并呈现从后端获取的注释。

首先,在下面的代码中,我在initialize函数中有_.bindAll(this, 'render', 'renderComments');。无论我是否执行_.bindAll(),在initialize()中调用this.render()this.renderComments()都没有问题。有没有_.bindAll()什么时候会帮助我们,什么时候不会帮助我们的例子?

ModalView = Backbone.View.extend({
    el: $('#modal'),
    template: _.template( $('#tpl_modal').html() ),
    initialize: function() {
        _.bindAll(this, 'render', 'renderComments');
        this.render();
        this.renderComments();
    },
    render: function() {
        $(this.el).fadeIn('fast').append( this.template( this.model.toJSON( this.model ) ) );
    },
    renderComments: function() {
        this.commentList = new CommentCollection();
        var self = this;
        this.commentList.fetch({
            data: { post_id: this.model.id},
            processData: true,
            success: function() {
                self.commentListView = new CommentListView({ collection: self.commentList });
            }
        });
    }
});

CommentListView = Backbone.View.extend({
    el: '.modal_comments',
    initialize: function() {
        this.render();
    },
    render: function() {
        var self = this;
        this.collection.each( function(comment, index) {
            $(self.el).append( new CommentListItemView({ model: comment }).render().el );
        });
        return this;
    }
});

第二,我对this.的准备工作感到困惑。例如,在renderComments中,为什么我不能使用:

var commentList = new CommentCollection();
var self = this;
commentList.fetch({.... });

对于行this.commentList = new CommentCollection();,除了实例化类CommentCollection()之外,它是否使commentList成为ModalView的子级?

此外,是否有必要拥有var self = this;并在稍后的回调函数中使用self.commentListView?可以使用绑定来访问this.commentListView吗?或者使用var self = this是传统的做事方式吗?

最后,是否应该将renderComments的成功函数中的self.commentListView = new CommentListView({ collection: self.commentList });移到CommentListView的初始化方法中,并绑定到this.collection.on('reset');,以防止嵌套过多的函数?这将导致:

ModalView = Backbone.View.extend({
    el: $('#modal'),
    template: _.template( $('#tpl_modal').html() ),
    initialize: function() {
        _.bindAll(this, 'render', 'renderComments');
        this.render();
        this.renderComments();
    },
    render: function() {
        $(this.el).fadeIn('fast').append( this.template( this.model.toJSON( this.model ) ) );
    },
    renderComments: function() {
        this.commentList = new CommentCollection();
        this.commentListView = new CommentListView({ collection: this.commentList });
        this.commentList.fetch({
            data: { post_id: this.model.id},
            processData: true
        });
    }
});
CommentListView = Backbone.View.extend({
    el: '.modal_comments',
    initialize: function() {
        this.collection.on('reset', this.render, this);
    },
    render: function() {
        var self = this;
        this.collection.each( function(comment, index) {
            $(self.el).append( new CommentListItemView({ model: comment }).render().el );
        });
        return this;
    }
});

phew--长问题;)

1) 当我第一次使用主干时,我曾经在初始化方法中执行_.bindAll,但后来我停止了。它通常是不需要的,除非你绑定到事件,然后它真的很有用。例如,如果您有:

events:
{
    'click': clickHandler
},
clickHandler: function(){
    //do cool stuff
}

那么做_.bindAll(this, 'clickHandler')是有帮助的,否则你的this指针将不是视图

2) 如果我理解您的问题:commentList成为您的ModalView实例的属性。

3) 使用var self = this;相对常见,但在许多情况下可以避免,因为Underscore.js中存在重载(这是主干.js的依赖项)。例如,大多数集合函数(mapeach等)都将上下文作为最后一个参数。所以不是

var self = this;
_.map([1,2], function(item){
    self.sum = self.sum + item; 
});

你可以做:

_.map([1,2], function(item){
    this.sum = this.sum + item; 
}, this);

如果你的情况,你可以用代替你的success方法

success: _.bind(function() {
             this.commentListView = new CommentListView({ collection: this.commentList });
         }, this);

如果你想了解更多关于这个指针有点令人困惑的主题的信息,建议你使用以下优秀的教程:http://bonsaiden.github.com/JavaScript-Garden/#function.this

4) 是--我会将渲染移到reset。这样,如果其他原因导致集合重置,则视图将拾取该集合。

希望我回答了你所有的问题。