我对backbone.js中绑定和_bind.All
的目的感到困惑。下面是一个工作代码,用于创建模态视图#modal
并呈现从后端获取的注释。
首先,在下面的代码中,我有initialize
函数_.bindAll(this, 'render', 'renderComments');
。无论我是否_.bindAll()
,我在this.render()
内调用this.renderComments()
和initialize()
都没有问题。是否有任何关于_.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
传统的做事方式?
最后,self.commentListView = new CommentListView({ collection: self.commentList });
的成功函数中的renderComments
应该转移到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;
}
});
答案 0 :(得分:8)
phew - 很长的问题;)
1)当我第一次使用骨干网时,我曾经在我的初始化方法中做_.bindAll
,但我已经停止了。除非你对事件具有约束力,否则它通常不需要,然后它才真正有用。例如,如果你有:
events:
{
'click': clickHandler
},
clickHandler: function(){
//do cool stuff
}
然后执行_.bindAll(this, 'clickHandler')
会很有帮助,否则你的this
指针将不会是视图
2)如果我理解您的问题:commentList
成为ModalView
实例的属性。
3)使用var self = this;
是比较常见的,但在很多情况下可以避免因为Underscore.js(这是backbone.js的依赖)的重载。例如,大多数集合函数(map
,each
等)将上下文作为最后一个参数。所以而不是
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
。这样,如果其他东西导致重置集合,视图就会把它拿起来。
希望我回答你所有的问题。