【问题标题】:Knockout JS: Fileupload eventKnockout JS:文件上传事件
【发布时间】:2013-06-24 13:12:08
【问题描述】:

我有这个用于上传文件的淘汰js脚本

此代码在用户在上传控件中选择文件时触发上传事件

上传.html

    $(function() {
        var viewModel = {
            filename:  ko.observable(""),
        };

        ko.applyBindings(viewModel);
    });

<form>
<input id="upload" name="upload" 
    data-bind="fileUpload: { property: 'filename', url: 'http://localhost/api/upload/PostFormData' }" 
    type="file" /> 

<button id="submitUpload">Upload</button>
</form>

文件上传.js

ko.bindingHandlers.fileUpload = {
init: function (element, valueAccessor) {
    $(element).after('<div class="progress"><div class="bar"></div><div class="percent">0%</div></div><div class="progressError"></div>');
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {


    var options = ko.utils.unwrapObservable(valueAccessor()),
        property = ko.utils.unwrapObservable(options.property),
        url = ko.utils.unwrapObservable(options.url);



    if (property && url) {

        $(element).change(function() {
            if (element.files.length) {
                var $this = $(this),
                    fileName = $this.val();

                // this uses jquery.form.js plugin
                $(element.form).ajaxSubmit({
                    url: url,
                    type: "POST",
                    dataType: "text",
                    headers: { "Content-Disposition": "attachment; filename=" + fileName },
                    beforeSubmit: function() {
                        $(".progress").show();
                        $(".progressError").hide();
                        $(".bar").width("0%")
                        $(".percent").html("0%");

                    },
                    uploadProgress: function(event, position, total, percentComplete) {
                        var percentVal = percentComplete + "%";
                        $(".bar").width(percentVal)
                        $(".percent").html(percentVal);

                    },
                    success: function(data) {
                        //$(".progress").hide();
                        //$(".progressError").hide();
                        // set viewModel property to filename
                        $("label[for='upload']").text(data);

                        bindingContext.$data[property](data);
                    },
                    error: function(jqXHR, errorThrown) {
                        $(".progress").hide();
                        $("div.progressError").html(jqXHR.responseText);
                    }
                });
            }
        });
    }
}

}

现在,我想把上传事件的触发移到提交按钮上

 <button id="submitUpload">Upload</button>

如何做到这一点?现在这就是我所在的位置,我只是将上传事件移动到按钮的单击事件中。但它不起作用,它不会调用 API 的 ajax 请求。

  $('#submitUpload').click(function () {

            if (element.files.length) {

                var $this = $(element),
                    fileName = $this.val();
                //alert(element.form);

                // this uses jquery.form.js plugin
                $(element.form).ajaxSubmit({
                    url: url,
                    type: "POST",
                    dataType: "text", 
                    headers: { "Content-Disposition": "attachment; filename=" + fileName },
                    beforeSubmit: function() {
                        $(".progress").show();
                        $(".progressError").hide();
                        $(".bar").width("0%")
                        $(".percent").html("0%");

                    },
                    uploadProgress: function(event, position, total, percentComplete) {
                        var percentVal = percentComplete + "%";
                        $(".bar").width(percentVal)
                        $(".percent").html(percentVal);

                    },
                    success: function(data) {
                        //$(".progress").hide();
                        //$(".progressError").hide();
                        // set viewModel property to filename
                        $("label[for='upload']").text(data);

                        bindingContext.$data[property](data);
                    },
                    error: function(jqXHR, errorThrown) {
                        $(".progress").hide();
                        $("div.progressError").html(jqXHR.responseText);
                    }
                });
            }
        });

【问题讨论】:

    标签: javascript jquery ajax knockout.js knockout-2.0


    【解决方案1】:

    绑定处理程序的 URL 不是只传递名称,而是从您的 ViewModel 对象传递第三个参数 (fileBinaryData),然后在 KO BindingHandler 的 Update 方法中读取文件内容,然后在 update 方法中更新第三个 observable (fileBinaryData)。

    然后你可以在你的视图模型中使用这个文件二进制数据

    所以对于按钮绑定点击事件和访问fileBinaryData observable,这将具有文件内容。

    绑定处理程序:

    ko.bindingHandlers.FileUpload = {
        init: function (element, valueAccessor) {
            $(element).change(function () {
                var file = this.files[0];
                if (ko.isObservable(valueAccessor())) {
                    valueAccessor()(file);
                }
            });
        },
        update: function (element, valueAccessor, allBindingsAccessor) {
            var file = ko.utils.unwrapObservable(valueAccessor());
            var bindings = allBindingsAccessor();
    
            if (bindings.fileBinaryData && ko.isObservable(bindings.fileBinaryData)) {
                if (!file) {
    
                    bindings.fileBinaryData(null);
                } else {
                    var reader = new window.FileReader();
                    reader.onload = function (e) {
    
                        bindings.fileBinaryData(e.target.result);
                    };
                    reader.readAsBinaryString(file);
                }
            }
        }
    }
    

    HTML:

    <input type="file" id="fileUpload" class="file_input_hidden" data-bind="FileUpload: spFile, fileObjectURL: spFileObjectURL, fileBinaryData: spFileBinary" /> 
    

    视图模型:

    var viewModel = {
            filename:  ko.observable(""),
            url:  ko.observable(),
            spFileBinary:ko.observable(),
          //Write your CLICK EVENTS
        };
    

    希望这会有所帮助:)

    【讨论】:

    • 嗨,我不能让这个工作......在 JSFiddle 上碰巧有一个工作版本吗?我得到元素是未定义的错误。我想我可能出于某些原因输入了错误的 ID。谢谢
    【解决方案2】:

    元素在点击时是未知的。你需要在表格上找到它。 用

    开始你的 click 函数的第一行
    element = $('#upload').get(0);
    

    并将您的按钮标签替换为以下内容

    <input type="button" id="submitUpload" value="Upload"></input>
    

    因为按钮标签会自动提交表单。

    【讨论】:

      猜你喜欢
      • 2013-11-10
      • 2012-02-29
      • 1970-01-01
      • 2011-02-10
      • 2013-12-22
      • 2018-04-10
      • 2016-12-03
      • 2013-09-30
      • 2014-06-16
      相关资源
      最近更新 更多