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

SB2*_*055 20 knockout.js

给出以下代码:

<input data-bind="event: { change: uploadImage(this.files[0]) }" style="width: 10px;" type="file">
Run Code Online (Sandbox Code Playgroud)

我收到错误提示"文件未定义".我正在尝试转换此演示:

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

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

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

nem*_*esv 42

你有两个问题:

  • 如果你只是uploadImage(this.files[0])在对象文字中写一个函数call(),它将在初始化对象文字时执行一次,所以当KO解析绑定时.因此,它将使用错误的参数执行一次,并且您更改事件将不起作用.您可以将其包装到匿名函数中.请参阅文档访问事件对象或传递更多参数部分.

  • this不参考当前元素在你需要使用的绑定$element来代替.

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

data-bind="event: { change: function() { uploadImage($element.files[0]) } }"
Run Code Online (Sandbox Code Playgroud)

演示JSFiddle.

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

Phi*_*ker 17

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

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

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();
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

例:

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());
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)