我尝试将视图对象作为上下文传递给fetch回调:
var List = Backbone.Collection.extend({
url: '/tree/list.php'
});
var list = new List();
var View = Backbone.View.extend({
test: 'ok',
initialize: function() {
list.fetch({
context: this
})
.done(function(){
alert(this.test);
});
}
});
var view = new View();
这样可以正常工作并提示“确定”,但是:
var List = Backbone.Collection.extend({
url: '/tree/list.php'
});
var list = new List();
var View = Backbone.View.extend({
test: 'ok',
initialize: function() {
list.fetch({
context: this,
success: function(){
alert(this.test);
}
});
}
});
var view = new View();
什么都不提醒。
在第二种情况下,尽管我显式传递context
参数,为什么上下文会丢失?
答案 0 :(得分:2)
这是因为在第一个示例中,您将回调附加到Collection.fetch返回的jqXHR,后者尊重Backbone.ajax传递给它的上下文参数。
您的第二个示例将成功回调传递给Collection,而Collection又由Backbone调用,而不是jQuery。因此忽略了上下文参数。看一下Backbone源代码就证实了这一点:
fetch: function(options) {
options = options ? _.clone(options) : {};
if (options.parse === void 0) options.parse = true;
var success = options.success;
var collection = this;
options.success = function(resp) {
var method = options.reset ? 'reset' : 'set';
collection[method](resp, options);
if (success) success(collection, resp, options);
collection.trigger('sync', collection, resp, options);
};
wrapError(this, options);
return this.sync('read', this, options);
},
在骨干网中,建议您使用事件和Backbone.View提供的listenTo
方法。此方法确保在调用事件处理程序时上下文正确,并且每当使用backbone.View.remove()移除视图时都会删除侦听器:
var MyView = Backbone.View.extend({
test: 'ok',
initialize: function(){
this.collection = new Backbone.Collection({url:'/endpoint');
this.listenTo(this.collection, 'sync', this.onSync);
},
onSync: function(){
alert(this.test); // Works
}
})
答案 1 :(得分:0)
最有可能发生这种情况是因为在调用成功函数时会丢失上下文。成功的背景是窗口元素。如果你想将此传递给成功,请在初始化函数中创建var self = this,然后再执行alert(self.test)
var View = Backbone.View.extend({
test: 'ok',
initialize: function() {
var self = this;
list.fetch({
success: function(){
alert(self.test);
}
});
}
});
作为替代方案,您也可以这样做:
var View = Backbone.View.extend({
test: 'ok',
initialize: function() {
list.fetch({
context: this,
success: function(collection,response,options){
alert(options.context.test);
}
});
}
});
答案 2 :(得分:0)
我相信这应该有效:
var View = Backbone.View.extend({
test: 'ok',
initialize: function() {
var that = this;
list.fetch({
// context: this,
success: function(){
alert(that.test);
}
});
}
});
问题是this
正在使用的内容。
在你的第二个例子中,this
看起来像是指向传递给list.fetch()
的对象文字(包含context
和success
属性的对象),这不是没有一个名为test的属性,因此它会提醒undefined
。