0

私は、リクエストが実行されているときに(学習目的で)gifのロードを設定するアプリ機能を書いています。私は AngularJS 1.4.5 の「Controller as」構文と John Papa スタイル ガイドを使用しています。そこで、現在のリクエストの量をサービスに渡すインターセプターを作成しました。

(function () {
    'use strict';
    angular
        .module('eventApp')
        .factory('requestInterceptorService', requestInterceptorService);

    requestInterceptorService.$inject = ['$q', 'loadingService'];

    function requestInterceptorService($q, loadingService) {

        var numLoadings = 0; 
        var requestInterceptorServiceFactory = {
            request: request,
            response: response,
            responseError: responseError
        };
        return requestInterceptorServiceFactory;

        function request(config) {
            numLoadings++;
            loadingService.setLoaderStatus(numLoadings);
            return config || $q.when(config);
        }
        function response(response) {
            numLoadings--;
            loadingService.setLoaderStatus(numLoadings);
            return response || $q.when(response);

        }
        function responseError(response) {
            numLoadings--;
            loadingService.setLoaderStatus(numLoadings);
            return $q.reject(response);
        }
    }
})();

これは、ロード中の画像を表示する必要があるかどうかを示すフラグisLoadgerEnabledを使用した私のloading.serviceです。

(function () {
    'use strict';
    angular
        .module('eventApp')
        .factory('loadingService', loadingService);

    function loadingService() {

        var isLoaderEnabled = false;

        var loadingServiceFactory = {
            setLoaderStatus: setLoaderStatus,
            getLoaderStatus: getLoaderStatus,
            isLoaderEnabled: isLoaderEnabled
        };

        return loadingServiceFactory;

        function setLoaderStatus(numberOfRequests) {
            var status = false;
            if (numberOfRequests === 0) {
                status = false;
            }
            if (numberOfRequests !== 0) {
                status = true;
            }
            isLoaderEnabled = status;
        }

        function getLoaderStatus() {
            return isLoaderEnabled;
        }
    }
})();

上記のコードは私にとってはうまくいきます。ビューには、インデックスコントローラーからのフラグをリッスンする、ロードイメージとng-show ディレクティブを含むdivがあります。

<div id="loaderDiv">
   <img src="client/assets/img/loader.gif" class="content-loader" 
        ng-show="index.isLoaderEnabled" />
</div> 

.controller('indexController', indexController);

    indexController.$inject = ['$location', 'authService', 'authModal', 'loadingService', '$scope'];

    function indexController($location, authService, authModal, loadingService, $scope) {
        var vm = this;

        vm.isLoaderEnabled = loadingService.isLoaderEnabled;
        //code with other functionality 

        $scope.$watch(function () {
            return loadingService.isLoaderEnabled;
        }, function (newValue) {
            vm.isLoaderEnabled = newValue;
        });
    }
})();

私の問題: vm.isLoaderEnabledはサービスで更新されず(実際には vm.isLoaderEnabled は常に false)、どこに問題があるのか​​ わかりません。この機能のための効率的で洗練されたソリューションを、おそらく $scope なしで (可能であれば) 書きたいと思います。質問、リファクタリングのアドバイス、またはデータをバインドして表示するためのより良いアイデアをお待ちしています。

4

1 に答える 1

0

わかりました、問題の解決策を見つけることができました。まず、loadingService のコードのその部分を指し示したいと思います。

var loadingServiceFactory = {
            setLoaderStatus: setLoaderStatus,
            getLoaderStatus: getLoaderStatus,
            isLoaderEnabled: isLoaderEnabled//<------1 line
        };

        return loadingServiceFactory;//<------2 line

1 行目でisLoaderEnabled をプロパティ isLoaderEnabledにコピーし、2 行目でそれを返します。したがって、loadingController は読み込みフラグのコピーを取得します。以前のコードが機能することがわかった場合 (他の多くのソリューションを試したため)。

それで、解決策。Observer パターンを使用することにしました。これは Angular ではあまり良い方法ではありませんが、うまくいきます (いずれにせよ、将来はコードを上書きします)。

  1. requestInterceptor - 変更なし

  2. ローディング サービス:

       (function () {
    'use strict';
    angular
        .module('eventApp')
        .factory('loadingService', loadingService);
    
    function loadingService() {
    
        var isLoaderEnabled = false;
        var callbacks = [];
        var loadingServiceFactory = {
            setLoaderStatus: setLoaderStatus,
            getLoaderStatus: getLoaderStatus,
            register: register
        };
    
        return loadingServiceFactory;
    
        function setLoaderStatus(numberOfRequests) {
            if (numberOfRequests === 0) {
                isLoaderEnabled = false;
            }
            if (numberOfRequests > 0) {
                isLoaderEnabled = true;
            }
            notify();
        }
    
        function getLoaderStatus() {
            return isLoaderEnabled;
        }
    
        function register(callback) {
            callbacks.push(callback);
        }
    
        function notify() {
            callbacks.forEach(function (callback) {
                callback();
            });
        }
    }
       })();
    
  3. ローディングコントローラー:

    (function () {
    'use strict';
    angular
        .module('eventApp')
        .controller('indexController', indexController);
    
    indexController.$inject = ['$location', 'authService', 'authModal', 'loadingService'];
    
    function indexController($location, authService, authModal, loadingService) {
        /* jshint validthis: true*/
        var vm = this;
        vm.loading = false;            
    
        vm.loaderObserver = function () {
            vm.loading = loadingService.getLoaderStatus();
        }
    
        loadingService.register(vm.loaderObserver);
    
        //other unnecessary code
    };
    })();
    
  4. ローダー div

        <div id="loaderDiv" ng-show="index.loading" >
                        <img src="client/assets/img/loader.gif" class="content-loader" />
                 </div>   
    

これが誰かを助けることを願っています。

于 2015-09-30T18:06:20.210 に答える