Knockout数组绑定只能工作一次

时间:2012-09-21 12:41:11

标签: javascript knockout.js

我正在制作文件上传代码,目前仅适用于Chrome和Firefox。它允许用户拖放上传的文件。上传进度显示在网格中。

这是html

<form id="fileUploadForm" action="home/upload" method="post" enctype="multipart/form-data">
    <input type="file" id="fileselect" name="files" multiple="multiple" />
    <div id="filedrag">Drop files here</div>
    <button type="submit" id="submitbutton">Upload Files</button>
</form>

<table class="datatable" data-bind="visible:files().length>0">
    <thead>
        <tr>
            <th>Name</th>
            <th>Status</th>
            <th>Upload progress</th>
            <th>Progress bar</th>
        </tr>
    </thead>
    <tbody data-bind="foreach:files">
        <tr>
            <td data-bind="text:name"></td>
            <td data-bind="text:status"></td>
            <td data-bind="text:percentUploaded"></td>
            <td>
              <progress max="100" data-bind="attr: {value:percentUploaded}"></progress>
              <span data-bind="text:$root.files().length"></span></td>
        </tr>

    </tbody>
</table>

<pre data-bind="text: ko.toJSON($data.files, null, 2)"></pre>

这是JavaScript:

var File = function (f) {
    this.name = f.name;
    this.type = f.type;
    this.size = f.size;
    this.lastModified = f.lastModifiedDate.toDateString();
    this.status = ko.observable(f.status);
    this.percentUploaded = ko.observable(0);
};

var ViewModel = function () {
    var self = this,
      maxFileSize = 5000000,
      onFileSelecting = function (e) {
          e.stopPropagation();
          e.preventDefault();
          e.target.className = (e.type == "dragover" ? "hover" : "");
      },
    onFileSelected = function (e) {
        onFileSelecting(e);// cancel event and hover styling
        var files = e.target.files || e.dataTransfer.files;
        for (var i = 0, f; f = files[i]; i++) {
            var validationResult = validate(f);
            f.status = validationResult || 'Uploading';
            self.addFile(f);
            uploadFile(f);
        }
    },
    validate = function (f) {
        if (f.size > maxFileSize)
            return 'Too large, should be less than 5MB';
        if (f.type.indexOf("text") != 0)
            return 'Wrong file type';
    },
    uploadFile = function (f) {
        var file = self.files()[0];

        var fd = new FormData();
        fd.append("files", f, f.name);

        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", function (e) {
            file.status("Uploaded " + parseInt(e.loaded / e.total * 100) + "%");
            file.percentUploaded(parseInt(e.loaded / e.total * 100));
        }, false);

        xhr.onreadystatechange = function (e) {
            if (xhr.readyState == 4) {
                file.status((xhr.status == 200 ? "success" : "failure"));
            }
        };

        xhr.open("POST", $("#fileUploadForm")[0].action, true);
        xhr.setRequestHeader("X_FILENAME", file.name);
        xhr.send(fd);
    };

    self.files = ko.observableArray();
    self.addFile = function (f) { self.files.unshift(new File(f)); };

    $(document).ready(function () {
        if (window.File && window.FileList && window.FileReader) {
            var fileSelector = $("#fileselect"),
              fileDragArea = $("#filedrag"),
              submitButton = $("#submitbutton");

            fileSelector.change(onFileSelected);
            var xhr = new XMLHttpRequest();
            if (xhr.upload) {
                filedrag.addEventListener("dragover", onFileSelecting, false);
                filedrag.addEventListener("dragleave", onFileSelecting, false);
                filedrag.addEventListener("drop", onFileSelected, false);
                filedrag.style.display = "block";
                submitbutton.style.display = "none";
                fileSelector.hide();
            }
        }
    });
};

var model = new ViewModel();
ko.applyBindings(model);

当我拖放一组文件时,一切正常。但是,当我拖放另一个集合时,文件数组会更新,但网格不会显示其他行。

然而,当我拿出这个HTML5标记时,一切正常:

<progress max="100" data-bind="attr: {value:percentUploaded}"></progress>

我创建了小提琴(http://jsfiddle.net/9aJtG/1),但它有其他问题 - 1)小提琴上的拖放只会打开文件(不知道为什么)2)删除文件提交的文件,但是没有服务器端代码可以使用JSFiddle表单发布

我已尝试使用另一个示例中的进度条,该示例没有此问题http://jsfiddle.net/bxfXd/800/

有什么想法吗?

非常感谢!

0 个答案:

没有答案