如何使用敲除绑定访问文件输入?

Posted

技术标签:

【中文标题】如何使用敲除绑定访问文件输入?【英文标题】:How to access file input with knockout binding? 【发布时间】:2013-05-31 14:50:40 【问题描述】:

给定以下代码:

<input data-bind="event:  change: uploadImage(this.files[0]) " style="width: 10px;" type="file">

我收到一条错误消息,提示“未定义文件”。我正在尝试转换此演示:

https://github.com/paulrouget/miniuploader/blob/gh-pages/index.html

对于淘汰赛友好的实施。加载页面时发生错误。如果用户指定了文件,我知道如何访问该文件吗?

jsfiddle:http://jsfiddle.net/LkqTU/9597/

【问题讨论】:

【参考方案1】:

这大概是最简单的一种了,上传前也可以看到预览图

<input type="file" data-bind="fileSrc: src" id="file"/>
<img data-bind="attr:src:src"/>

$(function() 
    ko.applyBindings(new ViewModel());
);

var ViewModel = function () 
    var self = this;

    self.src = ko.observable();
;

ko.bindingHandlers.fileSrc = 
    init: function (element, valueAccessor) 
        ko.utils.registerEventHandler(element, "change", function () 
            var reader = new FileReader();

            reader.onload = function (e) 
                var value = valueAccessor();
                value(e.target.result);
            

            reader.readAsDataURL(element.files[0]);
        );
    
;

【讨论】:

请解释你的代码是做什么的以及它是怎么做的。【参考方案2】:

对于任何感兴趣的人,您可以使用以下自定义绑定,它允许将文件输入元素绑定到包含 File 的可剔除 observable。

它处理将 observable 设置为所选文件(由 @nemesv 回答),以及在 observable 设置为 null 时清除输入元素(请参阅this 答案):

ko.bindingHandlers.fileUpload = 
    init: function (element, valueAccessor) 
        $(element).change(function () 
            valueAccessor()(element.files[0]);
        );
    ,
    update: function (element, valueAccessor) 
        if (ko.unwrap(valueAccessor()) === null) 
            $(element).wrap('<form>').closest('form').get(0).reset();
            $(element).unwrap();
        
    
;

示例:

function Example() 
  var self = this;

  self.uploadFile = ko.observable(null);
  self.uploadName = ko.computed(function() 
    return !!self.uploadFile() ? self.uploadFile().name : '-';
  );

  self.clear = function() 
    self.uploadFile(null);
  ;
;

ko.bindingHandlers.fileUpload = 
  init: function(element, valueAccessor) 
    $(element).change(function() 
      valueAccessor()(element.files[0]);
    );
  ,
  update: function(element, valueAccessor) 
    if (ko.unwrap(valueAccessor()) === null) 
      $(element).wrap('<form>').closest('form').get(0).reset();
      $(element).unwrap();
    
  
;

ko.applyBindings(new Example());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<input type="file" data-bind="fileUpload: uploadFile">
<br/>
<br/>Selected file name: <span data-bind="text: uploadName"></span>
<br/>
<button data-bind="click: clear">Clear input</button>

【讨论】:

【参考方案3】:

你有两个问题:

1234563因此它将使用错误的参数执行一次,并且您更改事件将不起作用。您可以通过将其包装到匿名函数中来使其工作。请参阅文档Accessing the event object, or passing more parameters section.

this 不引用绑定中的当前元素,您需要使用$element instead.

所以正确的绑定看起来像这样:

data-bind="event:  change: function()  uploadImage($element.files[0])  "

演示JSFiddle.

【讨论】:

我不确定它是否更漂亮 :-) 但我更喜欢 change:uploadImage.bind($data,$element.files[0])

以上是关于如何使用敲除绑定访问文件输入?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用敲除数据绑定在新选项卡中打开按钮链接

解决不一致的敲除检查绑定

如何使用敲除创建选择

如何在打字稿中定义敲除绑定处理程序?

如何将敲除数据绑定到没有名称的数组[重复]

输入按键的敲除事件绑定导致奇怪的行为