有什么方法可以使用 Backbone.js 及其模型架构,我可以将 formdata 对象发送到服务器?我遇到的问题是 Backbone 发送的所有内容都被编码为 JSON,因此 formdata 对象没有正确发送(显然)。
我正在通过发出直接的 jQuery ajax 请求并将 formdata 对象作为数据属性来临时解决这个问题,但这并不理想。
有什么方法可以使用 Backbone.js 及其模型架构,我可以将 formdata 对象发送到服务器?我遇到的问题是 Backbone 发送的所有内容都被编码为 JSON,因此 formdata 对象没有正确发送(显然)。
我正在通过发出直接的 jQuery ajax 请求并将 formdata 对象作为数据属性来临时解决这个问题,但这并不理想。
这是通过覆盖该sync
方法的解决方案,我使用该方法来允许文件上传。
在这种情况下,我会覆盖模型的sync
方法,但这也可以是Backbone.sync
方法。
var FileModel = Backbone.Model.extend({
urlRoot: CMS_ADMIN_URL + '/config/files',
sync: function(method, model, options){
// Post data as FormData object on create to allow file upload
if(method == 'create'){
var formData = new FormData();
// Loop over model attributes and append to formData
_.each(model.attributes, function(value, key){
formData.append(key, value);
});
// Set processData and contentType to false so data is sent as FormData
_.defaults(options || (options = {}), {
data: formData,
processData: false,
contentType: false
});
}
return Backbone.sync.call(this, method, model, options);
}
});
编辑:
要跟踪上传进度,您可以在选项中添加一个xhr
选项:
...
_.defaults(options || (options = {}), {
data: formData,
processData: false,
contentType: false
xhr: function(){
// get the native XmlHttpRequest object
var xhr = $.ajaxSettings.xhr();
// set the onprogress event handler
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
console.log('%d%', (event.loaded / event.total) * 100);
// Trigger progress event on model for view updates
model.trigger('progress', (event.loaded / event.total) * 100);
}
};
// set the onload event handler
xhr.upload.onload = function(){
console.log('complete');
model.trigger('progress', 100);
};
// return the customized object
return xhr;
}
});
...
只是为了添加这个问题的答案,这就是我如何去做而不必覆盖sync
:
在我看来,我有类似的东西:
$('#' + $(e.currentTarget).data('fileTarget')).trigger('click').unbind('change').bind('change', function(){
var form_data = new FormData();
form_data.append('file', $(this)[0].files[0]);
appManager.trigger('user:picture:change', form_data);
});
然后触发执行此操作的控制器中的函数:
var picture_entity = new appManager.Entities.ProfilePicture();
picture_entity.save(null, {
data: data,
contentType: false,
processData: false,
});
那时,我正在data
用我的FormData
对象覆盖 jQuery。
我有类似的要求,这就是我所做的:
在视图中:
var HomeView = Backbone.View.extend({
el: "#template_loader",
initialize: function () {
console.log('Home View Initialized');
},
render: function () {
var inputData = {
cId: cId,
latitude: latitude,
longitude: longitude
};
var data = new FormData();
data.append('data', JSON.stringify(inputData));
that.model.save(data, {
data: data,
processData: false,
cache: false,
contentType: false,
success: function (model, result) {
alert("Success");
},
error: function () {
alert("Error");
}
});
}
});
希望这可以帮助。
我遇到过同样的问题。您可以在上面看到我解决它的方式。
var $form = $("myFormSelector");
//==> GET MODEL FROM FORM
var model = new MyBackboneModel();
var myData = null;
var ajaxOptions = {};
// Check if it is a multipart request.
if ($form.hasFile()) {
myData = new FormData($form[0]);
ajaxOptions = {
type: "POST",
data: myData,
processData: false,
cache: false,
contentType: false
};
} else {
myData = $form.serializeObject();
}
// Save the model.
model.save(myData, $.extend({}, ajaxOptions, {
success: function(model, data, response) {
//==> INSERT SUCCESS
},
error: function(model, response) {
//==> INSERT ERROR
}
}));
hasFile 是扩展 JQuery 函数的自定义方法。
$.fn.hasFile = function() {
if ($.type(this) === "undefined")
return false;
var hasFile = false;
$.each($(this).find(":file"), function(key, input) {
if ($(input).val().length > 0) {
hasFile = true;
}
});
return hasFile;
};
只需使用Backbone.emulateJSON = true;
:http ://backbonejs.org/#Sync-emulateJSON
将导致 JSON 在模型参数下被序列化,并使用 application/x-www-form-urlencoded MIME 类型发出请求,就像来自 HTML 表单一样。
没有一个答案对我有用,下面是简单易行的解决方案。通过覆盖sync
方法,options.contentType
像这样:
sync: function(method, model, options) {
options = _.extend({
contentType : 'application/x-www-form-urlencoded;charset=UTF-8'
}, options);
options.data = jQuery.param(model.toJSON());
return Backbone.sync.call(this, method, model, options);
}
一个简单的,希望这会对某人有所帮助。
创建一个Backbone Model对象:
var importModel = new ImportModel();
调用 Backbone 模型的 Save[POST] 方法并传递 FormData 对象。
var objFormData = new FormData();
objFormData.append('userfile', files[0]);
importModel.save(objFormData, {
contentType: false,
data: objFormData,
processData: false,
success: function(data, status, xhr) { },
error: function(xhr, statusStr) { }
});