Угловой алгоритм: остановить двойной цикл ngFileUpload?

У меня есть контроллер:

app.controller('FileUploadController', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
    $scope.$watch('files', function () {
        $scope.upload($scope.files);
    });

    $scope.$watch('file', function () {
        if ($scope.files !== null) {
            $scope.upload([$scope.file]);
        }
    });

    $scope.upload = function (files) {
        $scope.log = '';
        if (files && files.length) {
            $scope.numberOfFiles = files.length;
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                if (file && !file.$error) {
                    Upload.upload({
                        url: 'http://localhost/Reconcile/index.php',
                        file: file
                        // fileName: i // to modify the name of the file(s)
                    }).progress(function (evt) {
                        var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                        $scope.log = progressPercentage;
                    }).success(function (data, status, headers, config) {
                        for (var j = 0; j < 2; j++) {
                            $scope.parsePapa(files[j], j);
                        }
                    }).error(function (data, status, headers, config) {
                        $scope.log = 'error status: ' + status;
                    });
                }   
            }
        }
    };
}]);

Который в основном используется для перетаскивания n-файла csv-файла через ngFileUpload, который затем анализируется Papa Parse. При моем вызове Papa Parse (расположенному в $scope.parsePapa) мне нужен второй аргумент, чтобы позже отправить информацию о том, какой файл был загружен (просто индекс подходит) для организационных целей, причем первым аргументом является сам файл. Проблема в том, что если для функции успеха я сделал что-то вроде этого:

}).success(function (data, status, headers, config) {
    $scope.parsePapa(files[i], i);
}

Что происходит то success вызывается только после завершения загрузки обоих файлов. К тому времени, i уже в 2 (в случае 2 файлов: 0 в первый раз, 1 для второго файла и 2 для второго файла). Если я использовал приведенный выше код, он не возвращает файл, так как индекс files[2] ничего не хранится в нем, если два файла были загружены.

Чтобы исправить это, я использовал цикл внутри цикла for, который будет повторяться по длине files и распечатать каждый file содержалась в files, Но, поскольку файлов будет несколько, текущее поведение (например, в случае загрузки двух файлов) состоит в том, что каждый файл анализируется дважды. Я анализирую CSV-файлы с 1 000 000 строк (которые сравниваются позже), поэтому загрузка дважды влияет на производительность.

Короче говоря, я ищу способ отправить каждый файл в $scope.parsePapa(file, fileNumber), только один раз.

Любая помощь будет принята с благодарностью. Я совершенно новичок в Angular, поэтому заранее прошу прощения, если я что-то упустил.


РЕДАКТИРОВАТЬ: Даниал решил проблему (см. Ниже). если кому-то интересно, окончательный код выглядел так:

app.controller('FileUploadController', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
$scope.$watch('files', function () {
    $scope.upload($scope.files);
});

function uploadFile(file, index) {
    Upload.upload({
        url: 'http://localhost/Reconcile/index.php',
        file: file
        // fileName: i // to modify the name of the file(s)
    }).progress(function (evt) {
        var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
        $scope.log = progressPercentage;
    }).success(function (data, status, headers, config) {
        $scope.parsePapa(file, index);
    }).error(function (data, status, headers, config) {
        $scope.log = 'error status: ' + status;
    });
}

$scope.upload = function (files) {
    $scope.log = '';
    if (files && files.length) {
        $scope.numberOfFiles = files.length;
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            if (file && !file.$error) {
                uploadFile(file, i);
            }
        }
    }
};

}]);

1 ответ

Решение

Если вы хотите узнать индекс загруженного файла, вы можете сделать это так:

 function uploadFile(file, index) {
    Upload.upload({....}).success(function() {
       $scope.parsePapa(file, index);
    })...;
 }

 $scope.upload = function (files) {
    if (files && files.length) {
       var file = files[i];
       if (file && !file.$error) {
          uploadFile(file, i);
       }
    }
 }

Также вам нужен только один из этих двух часов, если вы разрешаете несколько файлов, достаточно первого:

$scope.$watch('files', function () {
    $scope.upload($scope.files);
});

$scope.$watch('file', function () {
    if ($scope.files !== null) {
        $scope.upload([$scope.file]);
    }
});
Другие вопросы по тегам