Подтвердить что ты не робот

Angularjs $http и индикатор выполнения

Мне нужно загрузить файл, и я использую $http (этот код получается из моей функции .service()):

sendFile: function (params) {
            return $http({method : 'post',
                url : 'http://XXXXXXXXXXXXX/rest/file.json',
                headers : { 'X-CSRF-Token' : $cookies['csrftoken']},
                data : params
            })
        },

Теперь, для небольшого файла и хорошей строки нет проблем, но с большим файлом и/или с плохой/медленной линией возникает проблема UI: пользователь не может знать, когда загрузка будет завершена. Мне нужен индикатор выполнения.

Итак, у меня есть поиск в Интернете, но я не нашел решения. Есть ли возможность получить некоторый прогресс/уведомление от $http?

Я пробовал этот код без везения:

ProfileService.sendFile(data)
                    .then(function(ret) {
                            var uri = ret.data.uri;
                            scope.content = "Upload finished";

                            scope.postForm.fid = ret.data.fid;
                            scope.postForm.buttonDisabled = false;
                        },
                        function(error) {
                            scope.postForm.showError = true;
                            scope.postForm.errorMsg = error.data;
                        },
                        function(progress) {
                            console.log("inside progress");
                            console.log(progress)
                        }
                    );

Функция "прогресс" никогда не вызывается.

Я использую angular 1.2.x

Спасибо.

4b9b3361

Ответ 1

Вы можете использовать Angular панель загрузки. Он автоматически работает для запросов $http и не нуждается в какой-либо настройке, кроме добавления его как зависимости приложения.

angular.module('app', ['angular-loading-bar']); // that all

Ответ 2

Я очень рекомендую ng-progress. Это обрабатывает несколько запросов и в основном показывает аккуратный небольшой индикатор выполнения для всей активности http.

http://victorbjelkholm.github.io/ngProgress/

Ответ 3

Вы можете решить это, скрыв/показывая загрузочную панель. Начните показывать загрузочную панель после начала загрузки и удалите загрузочную панель при загрузке (в обработчике успеха из запроса $http).

Я создал простой jsfiddle, чтобы вы могли показать вам пример.
Я использую $timeout для моделирования запроса $http.

Разметка HTML:

<div ng-controller="MyCtrl">
    <!-- this can be an image if you want -->
    <p ng-show="loading">...LOADING...</p>

    <!-- Showing the status -->
    <p ng-hide="loading">{{status}}</p>
    <button type="button" ng-click="upload()">Do $http request</button>
</div>

Js Controller:

function MyCtrl($scope, $timeout) {
    $scope.status = 'Not started';
    $scope.loading = false;

    $scope.upload = function() {
        $scope.loading = true;
        // Simulating a http request with a timeout
        $timeout(function(){ 
            $scope.status = "Finished";
            $scope.loading = false;
        },3000);
    }
}

Для демонстрации того, как это работает, см. эту скрипту.

Обновление

Пояснения в комментариях, вы хотите отслеживать ход загрузки по процентам. например. Сколько% до завершения загрузки завершено

Вы должны проверить этот SO сообщение, где это уже обсуждалось.

Из принятого ответа:

Я не думаю, что для этого можно использовать $http.post().  Что касается клиентской стороны, он должен работать с браузером HTML5, но вам, вероятно, придется создать свой собственный объект XMLHttpRequest и onprogress прослушиватель. См. AngularJS: отслеживание каждого загружаемого файла одновременно для идей.

Ответ 4

Вы можете просто использовать eventHandlers $http service

как:

mainModule.service('File', function (Api) {

    var controller = 'files';

    function File(data) {
        this.$data = data;
    }

    File.__proto__ = File.prototype = {
        upload: function (progress) {
            var fd = new FormData();
            fd.append('file', this.$data);
            return pack('/upload').post(fd, {
                transformRequest: angular.identity,
                uploadEventHandlers: {'progress': progress},
                headers: {'Content-Type': undefined}
            });
        }
    };

    return File;
    function pack(action) {
        return Api(controller + action);
    }
});

Api - это служба для соединения с сервером api.

$data - это файловый объект с входа

Ответ 5

Если вы не хотите писать show hide в каждом одном методе http, тогда мы можем создать простую директиву, используя $http.pendingRequests.length и и что это.

Всякий раз, когда у нас будет какой-либо HTTP-запрос, он будет автоматически отображаться.

app.directive('loading', ['$http', function ($http) {
    return {
        restrict: 'A',
        link: function (scope, elm, attrs) {
            scope.isLoading = function () {
                return $http.pendingRequests.length > 0;
            };
            scope.$watch(scope.isLoading, function (v) {
                if (v) {
                    elm.show();
                } else {
                    elm.hide();
                }
            });
        }
    };
}]);

И HTML

 <div data-loading>
   Please wait...
 </div>

Подробнее см. в этом