J'ai besoin de télécharger le fichier et j'utilise $ http (ce code provient de ma fonction .service ()):
sendFile: function (params) {
return $http({method : 'post',
url : 'http://XXXXXXXXXXXXX/rest/file.json',
headers : { 'X-CSRF-Token' : $cookies['csrftoken']},
data : params
})
},
Maintenant, pour un petit fichier et une bonne ligne, il n'y a pas de problème, mais avec un gros fichier et/ou une mauvaise/lente ligne, il y a un problème d'interface utilisateur: l'utilisateur ne peut pas savoir quand le téléchargement sera terminé. J'ai besoin d'une barre de progression.
J'ai donc effectué une recherche sur Internet, mais je n'ai pas trouvé de solution. Est-il possible d’obtenir des progrès/notifications de $ http?
J'ai essayé ce code sans succès:
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)
}
);
La fonction "progress" n'est jamais appelée.
J'utilise angular 1.2.x
Merci.
Vous pouvez utiliser Barre de chargement angulaire . Cela fonctionne automatiquement pour $http
demande et ne nécessite aucune configuration, à moins de l’ajouter comme dépendance d’application.
angular.module('app', ['angular-loading-bar']); // that's all
Je recommande fortement ng-progress. Cela gère plusieurs requêtes et affiche essentiellement une petite barre de progression bien nette pour toutes les activités http.
Vous pouvez résoudre ce problème en masquant/affichant une barre de chargement. Commencez à afficher la barre de chargement une fois le téléchargement démarré et supprimez-la lorsque le téléchargement est terminé (dans le gestionnaire de succès de la $ requête http).
J'ai créé un simple jsfiddle pour vous montrer un exemple.
J'utilise $timeout
pour simuler un $http
demande.
Balisage 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);
}
}
Pour une démonstration de comment cela fonctionne, voir ce violon .
Mettre à jour
En clarifiant les commentaires, vous souhaitez pouvoir suivre l'avancement du téléchargement en pourcentage. par exemple. Combien de% jusqu'à ce que le téléchargement soit terminé
Vous devriez vérifier this SO post où cela a déjà été discuté.
De la réponse acceptée:
Je ne pense pas que $ http.post () puisse être utilisé pour cela. Côté client, il devrait fonctionner avec un navigateur HTML5, mais vous devrez probablement créer votre propre objet XMLHttpRequest et votre écouteur
onprogress
. Voir AngularJS: état du suivi de chaque fichier en cours de téléchargement simultanément pour des idées.
Vous pouvez simplement utiliser les eventHandlers du $ http service
comme:
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 est un service permettant de se connecter à l’API du serveur.
$ data est l’objet fichier de l’entrée
Si vous ne voulez pas écrire show hide dans chaque méthode http, nous pouvons créer une directive simple en utilisant $http.pendingRequests.length
et et c'est tout.
Chaque fois que nous aurons une demande http en cours, elle sera affichée automatiquement.
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();
}
});
}
};
}]);
ET HTML
<div data-loading>
Please wait...
</div>