使用Ember数据上传文件

时间:2012-02-08 19:24:06

标签: ember.js

有人可以使用EmberJS和Ember Data提供有关使用文件字段实现表单的代码示例或文档吗?

我已熟悉Ember Data,但我不确定如何正确实现文件上传。

4 个答案:

答案 0 :(得分:16)

以下是我编写的用于执行文件上传的em​​ber-data适配器的一部分(相同的服务器 - 不跨域)

DS.DjangoRESTAdapter = DS.RESTAdapter.extend({
        bulkCommit: false,

        createRecord: function(store, type, record) {
            var root = this.rootForType(type), json = {};

            var data = new FormData();
            data.append('username', record.get('username'));
            data.append('attachment', record.get('attachment'));

            this.django_file_ajax('http://localhost:8000/people/new/', "POST", {
                data: data,
                context: this,
                success: function(pre_json) {
                    json[root] = pre_json;
                    this.didCreateRecord(store, type, record, json);
                }
            });
        },

        django_file_ajax: function(url, type, hash) {
            hash.url = url;
            hash.type = type;
            hash.contentType = false;
            hash.processData = false;
            hash.context = this;

            jQuery.ajax(hash);
        }

    });

})();

因为我使用“FormData”助手进行多部分文件上传,所以它不是IE8友好的,但它是一个很好的概念证明。

以下是使用上述适配器的ember-data模型

PersonApp.Person = DS.Model.extend({
  id: DS.attr('number'),
  username: DS.attr('string'),
  attachment: DS.attr('string')
});

这是把手模板

<script type="text/x-handlebars" data-template-name="person">
{{view PersonApp.UploadFileView name="logo_image" contentBinding="content"}}
</script>

这是自定义余烬视图

PersonApp.PersonView = Ember.View.extend({
  templateName: 'person'
});

PersonApp.UploadFileView = Ember.TextField.extend({
    type: 'file',
    attributeBindings: ['name'],
    change: function(evt) {
      var self = this;
      var input = evt.target;
      if (input.files && input.files[0]) {
        var reader = new FileReader();
        var that = this;
        reader.onload = function(e) {
          var fileToUpload = e.srcElement.result;
          var person = PersonApp.Person.createRecord({ username: 'heyo', attachment: fileToUpload });
          self.get('controller.target').get('store').commit();
        }
        reader.readAsDataURL(input.files[0]);
      }
    }
});

如果你想在行动结账中看到一个完整的峰值,我最近做了一个多文件上传示例。

https://github.com/toranb/ember-file-upload

答案 1 :(得分:7)

这很简单,一般步骤是:

  1. 在Ember内连接输入。
  2. 从输入元素中指定的本地文件中读取数据。
  3. 将数据编码为base64。
  4. 将ember-data模型的值设置为base64字符串。
  5. 在服务器上解码base64字符串,瞧,您的二进制文件数据在服务器上。
  6. 应该注意的是,base64编码大文件存在性能问题,但对于较小的图像或文本,这不会有问题。


    您还可以将文件发送到Ember Data的“外部”,并通过pushPayload将响应(例如代表模型的JSON有效负载)推送到商店。如果是这样,可以使用FormData或XHR2中的其他方法。

    在此处阅读有关文件的客户端操作的更多信息: http://www.html5rocks.com/en/tutorials/file/dndfiles/

    在此处阅读有关文件上传的XHR2和FormData的更多信息: http://www.html5rocks.com/en/tutorials/file/xhr2/

答案 2 :(得分:7)

请看下面的链接。第一个链接或博客文章包含一个链接到一个工作的jsfiddle,用于处理与emberjs上传。注意我没有写博客或创建小提琴。但它应该可以解决你的问题。

http://chrismeyers.org/2012/06/12/ember-js-handlebars-view-content-inheritance-image-upload-preview-view-object-binding/ - 死链接

http://devblog.hedtek.com/2012/04/brief-foray-into-html5-file-apis.html

答案 3 :(得分:2)

我尝试了几种不同的解决方案,最后编写了FormData适配器和File转换。然后,任何需要上传文件数据的模型都可以使用FormDataAdapter并将文件属性定义为“file”类型:

应用程序/变换/ file.coffee

FileTransform = DS.Transform.extend
  serialize: (jsonData) ->
    jsonData

  deserialize: (externalData) ->
    externalData

应用程序/模型/ user.coffee

User = DS.Model.extend
    avatar: DS.attr('file')

应用程序/适配器/ form_data.coffee

get = Ember.get;

App.FormDataAdapter = ApplicationAdapter.extend
  ajaxOptions: (url, type, hash) ->
    hash = hash || {}
    hash.url = url
    hash.type = type
    hash.dataType = 'json'
    hash.context = @

    if hash.data and type != 'GET' and type != 'DELETE'
      hash.processData = false
      hash.contentType = false
      fd = new FormData()
      root = Object.keys(hash.data)[0]
      for key in Object.keys(hash.data[root])
        if hash.data[root][key]
          fd.append("#{root}[#{key}]", hash.data[root][key])

      hash.data = fd

    headers = get(@, 'headers')
    if headers != undefined
      hash.beforeSend = (xhr) ->
        for key in Ember.keys(headers)
          xhr.setRequestHeader(key, headers[key])

    hash

应用程序/适配器/ user.coffee

UserAdapter = FormDataAdapter.extend()

对于CoffeeScript感到抱歉,但它是从以下博客文章粘贴的:http://blog.mattbeedle.name/posts/file-uploads-in-ember-data/。你可以在那里阅读更详细的描述。此解决方案可能应与HTML5 FileReader输入结合使用,以启用图像预览和客户端文件类型验证。