Knockout JS:文件上传事件

Knockout JS: Fileupload event

本文关键字:事件 文件 JS Knockout      更新时间:2023-09-26

我有这个用于上传文件的淘汰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>

FileUpload.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);
                    }
                });
            }
        });

绑定处理程序的URL不是只传递名称,而是从ViewModel对象传递第三个参数(fileBinaryData),然后在KO bindinghandler的Update方法中读取文件Content,然后在Update方法中更新第三个可观察到的(fileBinary Data)。

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

因此,对于按钮绑定点击事件和访问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" /> 

ViewModel:

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

希望这有帮助:)

元素在单击时是未知的。你需要在表格上找到它。用启动点击功能的第一行

element = $('#upload').get(0);

并用以下替换您的按钮标签

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

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