23

angular js での読み込みインジケーターにはいくつかのアプローチがあることを私は知っています (これは、たとえば、https://gist.github.com/maikeldaloo/5140733 )。

ただし、呼び出しごとに構成する必要があるか、または、必要に応じてグローバルに動作する場合は、サービスで使用されている $q-promises ではなく、http-requests に適用するだけです。

これまで見てきたグローバル負荷インジケータは、

$httpProvider.responseInterceptors.push(interceptor);

$qのような に似たものはあり$qProvider.reponseInterceptorsますか? そうでない場合、そのような機能を実装する最も便利な方法は何ですか? たとえば、ある種のデコレータパターンを使用することは可能ですか?

4

4 に答える 4

9

現在の安定版 1.2.0 で動作する公式ドキュメントに良い例があります。

http://docs.angularjs.org/api/ng.$http (ページの上部 4 分の 1、Interceptors を検索)

これらのドキュメントを抽出すると、次の解決策にたどり着きます。

angular.module('RequestInterceptor', [])
  .config(function ($httpProvider) {
    $httpProvider.interceptors.push('requestInterceptor');
  })
  .factory('requestInterceptor', function ($q, $rootScope) {
    $rootScope.pendingRequests = 0;
    return {
           'request': function (config) {
                $rootScope.pendingRequests++;
                return config || $q.when(config);
            },

            'requestError': function(rejection) {
                $rootScope.pendingRequests--;
                return $q.reject(rejection);
            },

            'response': function(response) {
                $rootScope.pendingRequests--;
                return response || $q.when(response);
            },

            'responseError': function(rejection) {
                $rootScope.pendingRequests--;
                return $q.reject(rejection);
            }
        }
    });

その後、ng-show 式で pendingRequests>0 を使用できます。

于 2013-11-07T00:11:05.480 に答える
5

OP から要求されたので、これは現在取り組んでいるアプリに使用している方法に基づいています。このメソッドはの動作を変更するのではなく、ある種の視覚的な表示が必要な promise を処理するための非常に単純な$qAPI を追加します。これは、使用されるすべての場所で修正が必要ですが、ワンライナーに過ぎません。

使用法

ajaxIndicatorたとえば、UI の一部を更新する方法を知っているサービスがあります。promise のようなオブジェクトが、promise が解決されるまで指示を提供する必要がある場合は常に、次を使用します。

// $http example:
var promise = $http.get(...);
ajaxIndicator.indicate(promise); // <--- this line needs to be added

promise への参照を保持したくない場合:

// $http example without keeping the reference:
ajaxIndicator.indicate($http.get(...));

またはリソースを使用:

var rc = $resource(...);
...
$scope.obj = rc.get(...);
ajaxIndicator.indicate($scope.obj);

$then()(注: Angular 1.2 の場合、リソース オブジェクトにないため、微調整が必​​要になります。)

ルート テンプレートで、インジケーターを にバインドする必要があります$rootScope.ajaxActive

<div class="ajax-indicator" ng-show="ajaxActive"></div>

実装

(ソースから変更。) 警告: この実装では、ネストされた呼び出しが考慮されていません。(私たちの要件では UI のブロックが必要だったので、ネストされた呼び出しは想定していません。興味があれば、このコードを拡張してみることもできます。)

app.service("ajaxIndicator", ["$rootScope"], function($rootScope) {
    "use strict";

    $rootScope.ajaxActive = false;

    function indicate(promise) {
        if( !$rootScope.ajaxActive ) {
            $rootScope.ajaxActive = true;
            $rootScope.$broadcast("ajax.active"); // OPTIONAL
            if( typeof(promise) === "object" && promise !== null ) {
                if( typeof(promise.always) === "function" ) promise.always(finished);
                else if( typeof(promise.then) === "function" ) promise.then(finished,finished);
                else if( typeof(promise.$then) === "function" ) promise.$then(finished,finished);
            }
        }
    }

    function finished() {
        $rootScope.ajaxActive = false;
    }

    return {
        indicate: indicate,
        finished: finished
    };
});
于 2013-11-14T16:52:15.090 に答える
1

数週間前に同じ大きな質問があり、たまたま、アクション ボタンの読み込み状態と ng-repeat コンテンツの読み込みを表すいくつかのディレクティブを作成しました。

しばらく時間をかけて github にプッシュしました: https://github.com/ocolot/angularjs_loading_buttons

お役に立てば幸いです。

于 2013-07-18T21:28:49.497 に答える