我已经在网上搜寻了一整天,试图找到一个上传图片的完整示例,包括如何从backbone模型中创建一个普通的POST请求。初步调查后,我发现HTML5中的FileReader API可以实现这个功能。通过测试,我已经成功地在backbone之外通过创建XMLHttpRequest()来实现了这一点。
我现在要解决的问题是如何让backbone将FILES数据与POST请求一起发送,就像在常规多部分表单工作流程中那样。我对backbone还比较陌生,所以请原谅任何明显的错误。这是我目前的代码:
我现在要解决的问题是如何让backbone将FILES数据与POST请求一起发送,就像在常规多部分表单工作流程中那样。我对backbone还比较陌生,所以请原谅任何明显的错误。这是我目前的代码:
define(
[
'backbone'
],
function (Backbone) {
var Mock = Backbone.Model.extend({
url: '/api/v1/mocks',
idAttribute: '_id',
readFile: function(file){
var reader = new FileReader();
self = this;
reader.onload = (function(mockFile){
return function(e){
self.set({filename: mockFile.name, data: e.target.result});
};
})(file);
reader.readAsDataURL(file);
}
});
return Mock;
}
);
视图
define(
[
'jquery',
'backbone',
'underscore',
'text!../templates/create_mock-template.html',
'models/mock',
'collections/mocks'
],
function ($, Backbone, _, createMockTemplate, Mock, mocksCollection) {
var CreateMockView = Backbone.View.extend({
template: _.template(createMockTemplate),
events: {
'submit form': 'onFormSubmit',
'click #upload-link': 'process',
'change #upload': 'displayUploads'
},
initialize: function () {
this.render();
return this;
},
render: function () {
this.$el.html(this.template);
},
process: function(e){
var input = $('#upload');
if(input){
input.click();
}
e.preventDefault();
},
displayUploads: function(e){
// Once a user selects some files the 'change' event is triggered (and this listener function is executed)
// We can access selected files via 'this.files' property object.
var formdata = new FormData();
var img, reader, file;
var self = this;
for (var i = 0, len = e.target.files.length; i < len; i++) {
file = e.target.files[i];
if (!!file.type.match(/image.*/)) {
if (window.FileReader) {
reader = new FileReader();
reader.onloadend = function (e) {
self.createImage(e.target.result, e);
};
self.file = file;
reader.readAsDataURL(file);
}
}
}
},
createImage: function(source, fileobj) {
var image = '<img src="'+source+'" class="thumbnail" width="200" height="200" />'
this.$el.append(image);
},
onFormSubmit: function (e) {
e.preventDefault();
// loop through form elements
var fields = $(e.target).find('input[type=text], textarea');
var data = {};
// add names and vlaues to data object
$(fields).each(function(i, f) {
data[$(f).attr('name')] = $(f).attr('value');
});
// create new model from data
var mock = new Mock(data);
// this should set the filename and data attributes on the model???
mock.readFile(this.file);
// save to the server
mock.save(null, {
wait: true,
error: function(model, response) {
console.log(model)
},
success: function(model, response) {
mocksCollection.add(model);
console.log(model, response);
}
});
},
});
return CreateMockView;
}
);
我完全理解这可能有些模糊不清,它更多是一个概念验证而不是其他任何东西,并且也是学习backbone的好机会。因此,我的问题的关键是:
- 当backbone向api发送请求时,为什么我在向node / express服务器发送请求时没有看到数据和文件名属性?
- 我正在尝试做的事情是否可行,基本上我认为我应该能够读取数据attr并在服务器上创建图像?
- 是否有一种方法可以重写Mock model上的sync方法,并创建一个正确设置POST和FILES的请求。
我相信这是可能的,但我似乎找不到需要继续工作并使其正常工作的信息!
希望有人能帮助!
谢谢
编辑
只想提供更多信息,因为根据我的理解和与文档云IRC频道上的一些简短聊天,这应该有效。 因此,当我调用时
mock.readFile(this.file)
fileName和data属性似乎没有被设置。实际上,这里的控制台日志甚至似乎都没有触发,所以我猜这可能是问题所在。如果基于数据和文件名的值在节点端构建图像,我会对这种方法感到满意。那么为什么这些属性没有被设置并在post请求中传递到api呢?