Knockout JS:Fileupload事件

时间:2013-06-27 06:45:23

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

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

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

Upload.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>

怎么做?现在这就是我所在的位置,我只是在按钮的click事件中移动上传事件。但它不起作用,并且它不会向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);
                    }
                });
            }
        });

2 个答案:

答案 0 :(得分:3)

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

然后您可以在viewmodel中使用此filebinary数据

因此对于按钮绑定单击事件并访问将具有文件内容的fileBinaryData observable。

BindingHandler:

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
    };

希望这有助于:)

答案 1 :(得分:0)

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

开始点击功能的第一行
element = $('#upload').get(0);

并使用以下

替换您的按钮标记
<input type="button" id="submitUpload" value="Upload"></input>

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