【问题标题】:Ember.js value binding with HTML5 file uploadEmber.js 值绑定与 HTML5 文件上传
【发布时间】:2013-11-11 14:55:29
【问题描述】:

我离使用 Ember-data 上传文件不远了。但我没有得到正确的值绑定。下面是相关代码。

这是 App.js

App.LandcodeNewRoute = Ember.Route.extend({
    model: function () {
        return this.store.createRecord('landcode');
    },
    actions: {
        saveLandcode: function () {
            this.currentModel.save();
        }
    }
});


// REST & Model
App.ApplicationAdapter = DS.RESTAdapter.extend({
    namespace: 'api'
});
App.Store = DS.Store.extend({
    adapter: 'App.ApplicationAdapter'
});

App.Landcode = DS.Model.extend({
    code: DS.attr('string'),
    image: DS.attr('string')
});

// Views
App.UploadFile = Ember.TextField.extend({
    tagName: 'input',
    attributeBindings: ['name'],
    type: 'file',
    change: function (e) {
        var reader, that;
        that = this;
        reader = new FileReader();
        reader.onload = function (e) {
            var fileToUpload = e.target.result;

            console.log(e.target.result); // this spams the console with the image content
            console.log(that.get('controller')); // output: Class {imageBinding: Binding,

            that.get('controller').set(that.get('name'), fileToUpload);
        };
        return reader.readAsText(e.target.files[0]);
    }
});

HTML

<script type="text/x-handlebars" data-template-name="landcode/new">
    Code: {{input value=code}}<br />
    Image: {{view App.UploadFile name="image" imageBinding="Landcode.image" }}
    <button {{action 'saveLandcode'}}>Save</button>
</script>

正如您在 HTML 部分中看到的那样,我尝试将图像内容绑定到 Landcode 模型属性图像。没有大写L也试过了。

我想我不能像这样绑定图像,因为它是一个自定义视图对象?而且我认为通常它会自动绑定。也许我只是做了两次。

参考资料:

  1. http://emberjs.com/api/classes/Ember.Binding.html

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

  3. File upload with Ember data

  4. How: File Upload with ember.js

  5. http://discuss.emberjs.com/t/file-uploads-is-there-a-better-solution/765

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

【问题讨论】:

    标签: javascript html ember.js


    【解决方案1】:

    我将您的代码更新为以下内容:

    App.LandcodeNewRoute = Ember.Route.extend({
        model: function () {        
            return this.store.createRecord('landcode');
        },
        actions: {
            saveLandcode: function () {
                this.currentModel.save();
            }
        }
    });
    
    // REST & Model
    App.ApplicationAdapter = DS.RESTAdapter.extend({
        namespace: 'api'    
    });
    
    App.Landcode = DS.Model.extend({
        code: DS.attr('string'),
        image: DS.attr('string')
    });
    
    // views
    App.UploadFile = Ember.TextField.extend({
        tagName: 'input',
        attributeBindings: ['name'],
        type: 'file',
        file: null,
        change: function (e) {
            var reader = new FileReader(), 
            that = this;        
            reader.onload = function (e) {
                var fileToUpload = e.target.result;
                Ember.run(function() {
                    that.set('file', fileToUpload);
                });            
            };
            return reader.readAsDataURL(e.target.files[0]);
        }
    });
    

    App.UploadFile 中,我没有直接引用控制器,而是设置了file 属性。所以你可以绑定你的模型属性,使用视图:

    {{view App.UploadFile name="image" file=image }}
    

    Ember.run 用于您在测试应用时没有问题。

    请看看那个 jsfiddle http://jsfiddle.net/marciojunior/LxEsF/

    只需填写输入并单击保存按钮。您将在浏览器控制台中看到将发送到服务器的数据。

    【讨论】:

    • 感谢您的回答!发送到服务器工作!但是,我稍微编辑了您的答案,我提供的这行代码:return reader.readAsText(e.target.files[0]); 不正确。您已在答案中复制了它,但该图像不是真正的 base64 数据字符串。为此,我将该行更改为:return reader.readAsDataURL(e.target.files[0]);
    • 但在新的 ember 视图中不支持,
    【解决方案2】:

    我发现使用将数据 URI 附加到模型属性不允许上传超过大约 60k 的文件。相反,我最终为 ember-data 编写了一个表单数据适配器。这将使用FormData 上传所有模型数据。抱歉,它是在 CoffeeScript 而不是 JS 中,但它是从我的博客文章中粘贴的。你可以在http://blog.mattbeedle.name/posts/file-uploads-in-ember-data/阅读全文

    `import ApplicationAdapter from 'appkit/adapters/application'`
    
    get = Ember.get
    
    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
    
    `export default FormDataAdapter`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      • 1970-01-01
      • 2023-03-07
      • 2012-03-16
      • 2011-09-24
      • 2011-10-31
      • 1970-01-01
      相关资源
      最近更新 更多