web-dev-qa-db-fra.com

Angularjs $ http et barre de progression

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.

37
ZioBudda

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
51
Muhammad Reda

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.

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

6
mithun_daa

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.

3
aludvigsen

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

2
german meza

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>

Pour plus de détails, voir ceci

0
Ali Adravi