web-dev-qa-db-ja.com

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を使用しています

ありがとう。

37
ZioBudda

Angular Loading Bar を使用できます。 $httpリクエストに対して自動的に動作し、アプリの依存関係として追加する以外のセットアップは必要ありません。

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

Ng-progressを強くお勧めします。これは複数のリクエストを処理し、基本的にすべてのhttpアクティビティに対してすてきな小さなプログレスバーを表示します。

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

6
mithun_daa

これは、ローディングバーを非表示/表示することで解決できます。アップロードの開始後に読み込みバーの表示を開始し、アップロードが完了したら成功ハンドラー$ 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コントローラー:

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);
    }
}

この仕組みのデモンストレーションについては、 このフィドルを参照

更新

コメントを明確にすることで、アップロードの進行状況をパーセンテージで追跡できるようになります。 eg。アップロードが完了するまでの割合

this SO post これについては既に議論されています。

受け入れられた答えから:

これには$ http.post()を使用できるとは思わない。クライアント側については、HTML5ブラウザーで動作するはずですが、おそらく独自のXMLHttpRequestオブジェクトとonprogressリスナーを作成する必要があります。アイデアについては、 AngularJS:同時にアップロードされる各ファイルのステータスの追跡 を参照してください。

3
aludvigsen

$ httpサービス のeventHandlersを使用するだけです

好む:

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は入力からのファイルオブジェクトです

2
german meza

すべてのHTTPメソッドでshow hideを書きたくない場合は、$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>

詳細はこちらをご覧ください

0
Ali Adravi