4

因此,我已经在网上搜索了一天,试图找到一个完整的示例,说明如何上传图像以及来自骨干模型的正常 POST(创建)请求。所以经过一些初步的挖掘后,我发现了FileReaderHTML5 中的 api - 经过一些测试后,我通过创建一个 XMLHttpRequest()

我现在试图解决的问题是如何让 bacbone 发送 FILES 数据以及 POST 请求,就像您在正常的多部分表单工作流程中遇到的那样。我对骨干很陌生,所以请原谅任何明显的错误。这是我到目前为止所拥有的。

模型

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;
    }
);

我完全理解这可能有点摇摆不定,它比其他任何东西都更像是概念证明,也是学习骨干的好机会。所以我的问题的症结在于

  • 当请求由主干发送到 api 时,为什么我没有在对节点/快速服务器的请求中看到数据和文件名 attrs
  • 我想做什么甚至可能吗,我基本上认为我能够读取数据 attr 并在服务器上创建和映像?
  • 有没有办法覆盖 Mock 模型上的同步方法并创建正确设置的 POST 和 FILES 请求。

我确定这是可能的,但我似乎无法找到我需要耕耘并让它发挥作用的信息。!

希望有人能帮忙!

干杯

编辑

只是想根据我的理解提供更多信息,并在文档云 irc 频道上进行一些简短的聊天,这应该可以。所以当我打电话时

mock.readFile(this.file)

文件名和数据属性似乎没有设置。事实上,这里的控制台日志甚至似乎都被触发了,所以我猜这可能是问题所在。我会很高兴这种方法基本上基于数据和文件名的值在节点端构建图像。那么为什么不设置这些属性并在发布请求中传递给 api 呢?

4

2 回答 2

3

我已经解决了这种情况,将模型创建分为两个步骤:

  1. 基本信息
  2. 资产

例如,如果我的ModelFilm,我会展示一个只包含titlesynopsis的create-form。该信息被发送到服务器并创建模型。在下一步中,我可以显示更新表单,现在使用文件上传插件非常容易,例如:

您还可以查看他们的源代码以获取参考,以尝试通过文件创建解决方案实现一步主干模型

于 2012-08-27T12:28:19.117 回答
0

用于 express的 jquery-file-upload-middleware可能值得一提。

于 2013-07-12T20:44:29.183 回答