AngularJS: отслеживание состояния каждого загружаемого файла одновременно

После нажатия кнопки отправки, массив файлов ($scope.files, может быть как один файл, столько, сколько хочет пользователь) будет отправлено черезFormData а такжеXMLHttpRequest в моей угловой функции:$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 i увеличивается в начальном цикле for для каждого файла, и к тому времени, когда срабатывает прослушиватель событий,i уже увеличился выше запланированногоfiles[i] необходимое значение, влияющее только на последнее в массиве. я использую.uploadStatus в качестве средства для интерактивного отображения прогресса каждого отдельного файла пользователю, для этого мне нужно было бы иметь отдельных прослушивателей событий для каждого элемента массива в$scope.files, Как бы я назначал и отслеживал события для отдельных элементов массива в Angular?

ОБНОВИТЬ

Я переработал двух слушателей событий с небольшим успехом, но яя все еще испытываю странное поведение:

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 's двусторонняя привязка для своих шаблонов. за каждый элемент в массиве$scope.files статус присваивается с использованием вышеупомянутого.uploadStatus имущество. Теперь у меня естьsetTimeout склеить элементы из массива, с помощьюi переменная, которая 's передается в самоисполняющуюся функцию. Как ни странно, загрузка сейчас ограничивается примерно 6 одновременными загрузками одновременно, это должно быть проблемой на стороне сервера, но язаметив, что по мере сращивания элементов массиваng-repeat в шаблоне действует странно, где он будет склеивать элемент, не обязательно те, которые должны. Я'Мы также заметили, что часто есть записи, которые не сращиваются после достижения порога 2000 миллисекунд.

Это напоминает исходную проблему, где переменнаяi ненадежен при обращении к нему во время запуска прослушивателей событий? Теперь я передаю его анонимному самореализующемуся.onload функция, и соединение использует его, чтобы определить, какой элемент массива он должен удалить, но это неt обязательно удаляя правильный, и часто оставляя другие элементы в массиве, когда он должен их удалять.

Ответы на вопрос(2)

Ваш ответ на вопрос