AngularJS:跟踪每个文件的状态同时被上传 [英] AngularJS: tracking status of each file being uploaded simultaneously

查看:131
本文介绍了AngularJS:跟踪每个文件的状态同时被上传的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当pressing一个提交按钮,文件的数组( $ scope.files ,可以少为一个文件,如用户希望尽可能多)通过获取 FORMDATA XMLHtt prequest 在我的角度功能 $ scope.uploadFiles提交

Upon pressing a submit button, an array of files ($scope.files, can be as little as one file, as many as the user wants) gets submitted via FormData and XMLHttpRequest in my angular function $scope.uploadFiles:

$scope.uploadFiles = function() {
    for (var i in $scope.files) {
        var form = new FormData();
        var xhr = new XMLHttpRequest;

            // Additional POST variables required by the API script
        form.append('destination', 'workspace://SpacesStore/' + $scope.currentFolderUUID);
        form.append('contenttype', 'idocs:document');
        form.append('filename', $scope.files[i].name);
        form.append('filedata', $scope.files[i]);
        form.append('overwrite', false);

        xhr.upload.onprogress = function(e) {
            // Event listener for when the file is uploading
            $scope.$apply(function() {
                var percentCompleted;
                if (e.lengthComputable) {
                    percentCompleted = Math.round(e.loaded / e.total * 100);
                    if (percentCompleted < 1) {
                                            // .uploadStatus will get rendered for the user via the template
                        $scope.files[i].uploadStatus = 'Uploading...';
                    } else if (percentCompleted == 100) {
                        $scope.files[i].uploadStatus = 'Saving...';
                    } else {
                        $scope.files[i].uploadStatus = percentCompleted + '%';
                    }
                }
            });
        };

        xhr.upload.onload = function(e) {
            // Event listener for when the file completed uploading
            $scope.$apply(function() {
                $scope.files[i].uploadStatus = 'Uploaded!'
                setTimeout(function() {
                    $scope.$apply(function() {
                        $scope.files[i].uploadStatus = '';
                    });
                }, 4000);
            });
        };

        xhr.open('POST', '/path/to/upload/script');
        xhr.send(form);
    }

}

问题是, VAR我的增量在最初的for循环每个文件,由当时的事件监听器火, I 已经过去递增[I] 值所需的意图文件,只影响数组中的最后一次。我使用 .uploadStatus 为手段,以交互方式显示每个单独的文件到用户的进度,为此我需要为每个数组元素单独的事件侦听器 $ scope.files 。我将如何分配和跟踪单独的数组元素事件角?

The problem is that var i increments in the initial for loop for each file, and by the time the event listeners fire, i has already incremented past the intended files[i] value needed, only effecting the last in the array. I use .uploadStatus as a means to interactively show the progress of each individual file to the user, therefor I would need to have separate event listeners for each array element in $scope.files. How would I assign and track events for individual array elements in Angular?

更新

我修改了两个事件侦听器,一点点的成功,但我仍然遇到奇怪的行为:

I reworked the two event listeners, with a little success, but I'm still experiencing odd behavior:

xhr.upload.onprogress = (function(file) {
    // Event listener for while the file is uploading
    return function(e) {
        $scope.$apply(function() {
            var percentCompleted = Math.round(e.loaded / e.total * 100);
            if (percentCompleted < 1) {
                file.uploadStatus = 'Uploading...';
            } else if (percentCompleted == 100) {
                file.uploadStatus = 'Saving...';
            } else {
                file.uploadStatus = percentCompleted + '%';
            }
        });
    }
})($scope.files[i]);

xhr.upload.onload = (function(file, index) {
    // Event listener for when the file completed uploading
    return function(e) {
        $scope.$apply(function() {
            file.uploadStatus = 'Uploaded!'
            setTimeout(function() {
                $scope.$apply(function() {
                    $scope.files.splice(index,1);
                });
            }, 2000);
        });
    }
})($scope.files[i], i);

.onprogress 似乎熄灭顺利,但与 .onload 做了一些小的变化,我我现在看到了很多怪异的行为与它的模板AngularJS的双向绑定。在阵列中的每个elemnt $ scope.files 状态给出,使用上述 .uploadStatus 属性。现在我遇到的的setTimeout 拼接从数组中的元素,通过 I 是在获得通过的自变量-executing功能。奇怪的是上传的封盖在在现在的时间约为6同时上传,这必须是一个服务器端的问题,但我注意到,作为数组元素越来越拼接,在 NG-重复在模板奇怪行事那里将拼接的的元素,不一定是那些它应该。我也注意到,有常,2000年毫秒阈值击中后没有得到拼接项。

.onprogress seems to go off without a hitch, but with some small changes made to .onload, I am now seeing a lot of weird behavior with AngularJS's two-way binding for its templates. for each elemnt in array $scope.files a status is given, using the the aforementioned .uploadStatus property. Now I am having the setTimeout splice the elements from the array, via the i variable that's getting passed in to the self-executing function. Oddly enough the uploads are capping at around 6 simultaneous uploads at a time now, that must be a server side issue, but I'm noticing that as array elements are getting spliced, the ng-repeat in the template is acting bizarrely where it will splice an element, not necessarily the ones it should. I've also noticed that there are often entries that do not get spliced after the 2000 millisecond threshold is hit.

这让人想起原来的问题,在整个时的事件侦听器的触发参考变量 I 是靠不住的?现在我将其传递到匿名自执行 .onload 功能,并且拼接正在使用它,以确定哪些数组元素应该除去,但它不一定除去正确的,而且往往在离开阵列中的其他元素时,它应该是除去它们。

This is reminiscent of the original problem where the variable i is unreliable when referenced throughout the triggering of the event listeners? Now I am passing it in to the anonymous self-executing .onload function, and the splice is using it to determine what array element it should remove, but it isn't necessarily removing the correct one, and often leaving other elements in the array when it should be removing them.

推荐答案

首页传递给处理程序参照指数的原始数组中的事件。每次成功调用后拼接,数组的变化和指数不再指向同样的事情。

The index you pass to the event handlers refer to the indices in the original array. After every successful call to splice, the array changes and indices are no longer pointing to the same thing.

$scope.files = ['a.jpg', 'b.jpg', 'c.jpg'];
// $scope.files[1] = 'b.jpg'

$scope.files.splice(1,1);
// $scope.files = ['a.jpg', 'c.jpg']
// $scope.files[1] = 'c.jpg'

这篇关于AngularJS:跟踪每个文件的状态同时被上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆