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
Спасибо.
Ответы
Ответ 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>
Подробнее см. в этом