我正在创建一个连接到 RESTful 后端的主干应用程序。当我在模型上调用 save() 时,它将发布数据作为字符串化 JSON 发送:
{"firstName":"first","lastName":"last","Email":"email@gmail.com"}
但我的服务器希望它像查询字符串一样格式化:
firstName=first&lastName=last&Email=email@gmail.com
有没有办法让主干以不同的方式发送它?
我正在创建一个连接到 RESTful 后端的主干应用程序。当我在模型上调用 save() 时,它将发布数据作为字符串化 JSON 发送:
{"firstName":"first","lastName":"last","Email":"email@gmail.com"}
但我的服务器希望它像查询字符串一样格式化:
firstName=first&lastName=last&Email=email@gmail.com
有没有办法让主干以不同的方式发送它?
Backbone 没有提供任何开箱即用的东西。
但是很容易根据您的需要覆盖和定制它。
看看源代码: http ://documentcloud.github.com/backbone/docs/backbone.html
并检查 call save
,它将sync
在后台触发呼叫。
所以你需要的是Backbone.sync
用你自己的覆盖函数。
我会修改以下部分:
if (!options.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
和
if (!options.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = $.param(model); // <-- CHANGED
}
注意我正在使用jQuery 参数
如果您想使用自定义函数,请检查以下问题: Javascript 对象的查询字符串编码
[更新]
无需直接修改。最好用您自己的函数“Backbone.sync”覆盖它检查主干存储库的“TODO”示例。它有一个localStorage.js
覆盖 Backbone.sync 函数的文件https://github.com/documentcloud/backbone/tree/master/examples
我在工作中遇到了这个问题,Backbone.emulateJSON 也对我不起作用。在一些帮助下,我能够想出这个解决方法。我们覆盖 Backbone.ajax 函数并将 contentType 更改为“application/x-www-form-urlencoded”并使用 $.param 正确序列化数据。
Backbone.ajax = function() {
if(arguments[0].data && arguments[0].contentType == "application/json"){
arguments[0].data = $.param(JSON.parse(arguments[0].data));
arguments[0].contentType = "application/x-www-form-urlencoded";
}
return Backbone.$.ajax.apply(Backbone.$, arguments);
}
Backbone.sync 使用jQuery.ajax函数,因此我们可以修改 jqXHR 或发送到服务器的数据(通过 beforeSend)。
var oldSync = Backbone.Model.prototype.sync;
var SomeModel = Backbone.Model.extend({
url: 'test.json',
defaults: {
id: 1,
foo: 'test'
},
sync: function (method, model, options) {
// options are passed to the jQuery.ajax
_.extend(options, {
emulateHTTP: true,
emulateJSON: false,
beforeSend: function(xhr, settings) {
// settings.data is a body of our request.
if (_.isString(settings.data)) {
// settings.data is a JSON-string like '{"id":1, "foo":"test"}'
settings.data = Backbone.$.parseJSON(settings.data);
}
settings.data = Backbone.$.param(settings.data);
// settings.data is 'id=1&foo=test'
}
});
oldSync.apply(this, arguments);
}
});
var model = new SomeModel();
model.save();
实际上我们可以创建一个mixin!:)
我通过覆盖模型的同步功能来做到这一点:
var MyModel = Backbone.Model.extend({
"sync": function(method, model, options) {
if (method == "update" || method == "create") {
options = options ? _.clone(options) : {};
options['data'] = $.param(this['attributes']);
}
var arguments = [method, model, options];
return Backbone.sync.apply(this, arguments);
}
});
也许这可以帮助你,试试: http ://backbonejs.org/#Sync-emulateJSON
我找到解决方案,请参阅:
我用
Backbone.emulateJSON = true;
我写了“更新”案例:
options.url = "/user/"+Math.random(1, 1000);
options.type = "POST";
//.1/2 WORK
//options.data = (model instanceof Backbone.Model)?model.toJSON():{};
options.data = model.toJSON();
break;