AngularJS: status śledzenia każdego przesyłanego pliku jednocześnie

Po naciśnięciu przycisku wysyłania tablica plików ($scope.files, może być tylko jeden plik, tyle ile chce użytkownik, zostaje przesłany za pośrednictwemFormData iXMLHttpRequest w mojej funkcji kątowej$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);
    }

}

Problemem jestvar i inkrementuje początkową pętlę for dla każdego pliku, a do czasu wystrzelenia detektorów zdarzeńi już przekroczył zamierzonefiles[i] potrzebna wartość, wpływająca tylko na ostatnią w tablicy. używam.uploadStatus jako środek do interaktywnego pokazywania użytkownikowi postępów poszczególnych plików, dlatego musiałbym mieć osobne detektory zdarzeń dla każdego elementu tablicy w$scope.files. Jak przypisać i śledzić zdarzenia dla poszczególnych elementów tablicy w Angular?

AKTUALIZACJA

Przerobiłem dwóch słuchaczy zdarzeń, z niewielkim sukcesem, ale wciąż doświadczam dziwnego zachowania:

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 Wydaje się, że idzie bez problemu, ale z niewielkimi zmianami.onload, Widzę teraz wiele dziwnych zachowań z dwukierunkowym powiązaniem AngularJS dla jego szablonów. dla każdego elementu w szyku$scope.files podany jest status przy użyciu powyższego.uploadStatus własność. Teraz mamsetTimeout łącz elementy z tablicy, poprzezi zmienna, która jest przekazywana do funkcji samoczynnie wykonującej. Dziwne, że przesyłanie jest ograniczone do około 6 jednoczesnych wysyłek w danym momencie, co musi być problemem po stronie serwera, ale zauważam, że w miarę łączenia elementów tablicyng-repeat w szablonie działa dziwacznie tam, gdzie się splotniena element, niekoniecznie te, które powinien. Zauważyłem również, że często są wpisy, które nie są łączone po osiągnięciu progu 2000 milisekund.

Przypomina to oryginalny problem, w którym zmiennai jest niewiarygodny, gdy jest używany podczas wyzwalania detektorów zdarzeń? Teraz przekazuję to anonimowemu samoczynnemu wykonywaniu.onload funkcja, a połączenie używa jej do określenia, który element tablicy powinien usunąć, ale niekoniecznie usuwa poprawny i często pozostawia inne elementy w tablicy, gdy powinien je usunąć.

questionAnswers(2)

yourAnswerToTheQuestion