我正在学习backbone.js,并对此感到困惑: 我正在按照教程: http://arturadib.com/hello-backbonejs/
你可以在第一个例子(1.js)中看到:
(function($){
var ListView = Backbone.View.extend({
el: $('body'), // attaches `this.el` to an existing element.
initialize: function(){
_.bindAll(this, 'render'); // fixes loss of context for 'this' within methods
this.render(); // not all views are self-rendering. This one is.
},
render: function(){
$(this.el).append("<ul> <li>hello world</li> </ul>");
}
});
var listView = new ListView();
})(jQuery);
但是,如果我发表评论:_.bindAll(this, 'render');
,这仍然有效。我在谷歌搜索过,有人说方法bindAll()
是必要的,因为如果我切换上下文,this.render
的调用可能无法使用。我对“背景”感到困惑。当呼叫(this.render
)不可用时,有人可以解释一下吗?
答案 0 :(得分:28)
对于您给出_.bindAll(this, 'render');
的示例,没有必要,但如果您有回调函数,其中this
可能会更改为其他内容的上下文,那么_bindAll()
可以是方便。
例如:
initialize: function(){
_.bindAll(this, 'render', 'clickFunc');
},
events: {
'click .someElement': 'clickFunc'
},
clickFunc: function(e) {
/** If you remove the clickFunc from the list of events in bindAll,
'this' will refer to the element that invoked the event.
Adding the clickFunc event in the _.bindAll, ensures that 'this' stays
as the view.
*/
this /** <-- our focal point */
}
答案 1 :(得分:10)
bindAll
手动绑定
片段:
events: {
'click .win': 'win',
'click .lose': 'lose'
},
initialize: function () {
//win and lose are automatically bound for you
//because they are in the events property
//refresh must be manually bound
this.model.on('change', this.refresh);
//which you can do ECMA5 style if you like
this.model.on('change', this.refresh.bind(this));
//OR you can provide a context backbone style
this.model.on('change:foo', this.fooChange, this);
//However, since you pretty much never want an unbound function
//in a view, you can just stick this in all your initialize methods
//and call it done
//Note this will bind all functions in your view class if you don't
//pass specific method names. I recommend this form.
_.bindAll(this);
},
win: function () {...},
lose: function () {...},
refresh: function () {...},
fooChange: function() {...}
... OOOOORRRR 只需使用CoffeeScript和胖箭头,并在语言级别干净利落地解决这个问题。
答案 2 :(得分:2)
在这种情况下,您不需要_.bindAll
,但是请说您的观点有一种导致重新渲染的方法,您可以这样做:
..,
myMethod: function() {
this.$('.someselector').change(this.render);
},
如果您_.bindAll
没有render
,则您的上下文将会关闭。
答案 3 :(得分:2)
让我们仔细看看_.bindAll
_.bindAll = function(obj) {
var i, length = arguments.length, key;
if (length <= 1) throw new Error('bindAll must be passed function names');
for (i = 1; i < length; i++) {
key = arguments[i];
obj[key] = _.bind(obj[key], obj);
}
return obj;
};
做了什么。
events
它的作用是自动将其所有功能绑定到正确的上下文。 (声明其功能而不是调用它。
我个人认为Backbone.js的旧版本绑定其View
或DOM动作侦听器是一种约定。由于新版本Backbone events
在Binding "this"
中自动绑定和取消绑定侦听器。通过搜索{{1}} underscore.js offical docs
我希望它有所帮助。