我是RequireJS和Backbone的新手,并试图理解为什么ajax(fetch)代码不能正常工作。
require.config({
shim: {
'backbone': {
deps:['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
}
},
paths: {
'jquery': 'vendor/jquery/jquery',
'underscore': 'vendor/underscore/underscore',
'backbone': 'vendor/backbone/backbone'
}
});
require(['views/appViews'], function(AppView) {
new AppView();
});
define(['jquery', 'underscore','backbone', '../collections/appCollections'], function($, _, Backbone, AppCollections) {
var App = Backbone.View.extend({
initialize: function() {
_.bindAll( this, "render" );
this.collection = new AppCollections;
var $this = this;
this.collection.bind("all", this.render, this);
var x = this.collection.fetch();
/*
* This was not working
this.collection.fetch({
success: function() {
$this.render();
}
});
*/
},
template: _.template( $('#tweetsTemplate').html() ),
render: function() {
console.log(this.collection.toJSON());
//$(this.el).html(this.template({ tweets: this.collection.toJSON() }));
}
});
return App;
});
define(['jquery','underscore','backbone','../models/appModels'], function($, _, Backbone, AppModel) {
var AppCollection = Backbone.Collection.extend({
model: AppModel,
url: 'http://search.twitter.com/search.json?q=dog',
parse: function ( response, xhr ) {
return response.results;
},
// Overwrite the sync method to pass over the Same Origin Policy
sync: function (method, model) {
var $this = this;
var params = _.extend({
type: 'GET',
dataType: 'jsonp',
url: $this.url,
processData: false
} );
return $.ajax(params);
}
});
return AppCollection;
});
define(['underscore', 'backbone'], function(_, Backbone) {
var AppModel = Backbone.Model.extend({});
return AppModel;
});
问题是:一旦获取了集合,就不会调用render方法。开发人员工具中也没有错误。所以不确定在哪里看。
任何指针都很有用。
由于 病毒
答案 0 :(得分:1)
当您覆盖主干中的同步方法时,它不会正确触发事件。试试overwriting the sync method this way
或者,您可以简单地使您的成功功能看起来像主干来源:
success = function(resp) {
if (success) success(model, resp, options);
model.trigger('sync', model, resp, options);
};
答案 1 :(得分:1)
未调用成功回调,因为您的sync
方法未将其传递给ajax
。
sync
的第三个参数是options对象,其中包含成功回调。
sync: function (method, model, options) {
var $this = this;
var success = options.success;
options.success = function(resp) {
if (success) success(model, resp, options);
model.trigger('sync', model, resp, options);
};
var params = _.extend({
type: 'GET',
dataType: 'jsonp',
url: $this.url,
processData: false
}, options);
return $.ajax(params);
}
这样,ajax
将正确调用Backbone Collection的fetch
中定义的成功回调,后者将调用您传递给fetch的成功回调。
然后获取:
this.collection.fetch({
success: function() {
$this.render();
}
});
以下是来自Backbone source的fetch
。您可以看到它将success
回调传递给sync
。
fetch: function(options) {
options = options ? _.clone(options) : {};
if (options.parse === void 0) options.parse = true;
var success = options.success;
options.success = function(collection, resp, options) {
var method = options.update ? 'update' : 'reset';
collection[method](resp, options);
if (success) success(collection, resp, options);
};
return this.sync('read', this, options);
},
答案 2 :(得分:0)
很好的回应保罗,但只是想指出以下几点:
当试图通过覆盖fetch的成功函数来从ajax调用中检索数据时,我必须对你的代码进行以下修改:
sync: function (method, model, options) {
var $this = this;
var success = options.success;
options.success = function(resp) {
if (success) success(resp);
model.trigger('sync', model, resp, options);
};
var params = _.extend({
type: 'GET',
dataType: 'jsonp',
url: $this.url,
processData: false
}, options);
return $.ajax(params);
}
注意行中的差异:
if (success) success(resp);
这是为了正确传递成功函数的响应,否则它被模型覆盖。现在,在fetch的成功函数中,您可以输出数据:
var $this = this;
this.collection.fetch({
success: function(collection, response, options){
$this.render(response);
}
});
将ajax数据(响应)传递给render函数以执行您喜欢的操作。当然,您也可以事先以任何方式操纵数据。
理想情况下,我希望能够将数据传递到collection.models对象,就像Backbone默认情况下那样。我认为它与数据的解析方式有关,但我还没想到它。如果有人有解决方案,我很乐意听到:)
<强>更新强>
我设法覆盖了parse函数并以这种方式处理来自我的ajax调用的JSON数据,以便保持Backbone构造其集合对象的方式。这是代码:
parse: function(resp){
var _resp = {};
_resp.results = [];
_.each(resp, function(model) {
_resp.results.push(model);
});
return _resp.results;
}
这将创建一个新对象,其中包含一个名为 results 的模型数组,然后将其返回到您的fetch函数,允许您直接访问每个模型的属性。