2017-08-28 7 views
0

は、ここで設定し、値を得るために、私の基本的なサービスです見コントローラでサービス変数を設定し、他のどこでも$せずにそれをGET使用します会社のオプションを取得および設定するためのhttpリクエスト(約束付き)。私はこれを一度だけ行います。AngularJSは

.controller('global', ['$scope', '$http', '$api', '$location', '$translate', '$rootScope', '$timeout', '$filter', 'toastr', '$window', 'flag', 'companyService', function ($scope, $http, $api, $location, $translate, $rootScope, $timeout, $filter, toastr, $window, flag, companyService) { 
$api('GetCompanyOptions', {}) 
    .then(function (response) { 
     $scope.companyOptions = response.data 
     // doing stuff with the response first 
     // ... 
     // and setting the value to companyService 
     companyService.setOptions($scope.companyOptions) 
    }) 
}]) 

ほとんどすべてのコントローラとディレクティブで、この値を使用します。しかし、httpコールには時間がかかるため、タイミングに問題が多かったので、時には空の値が次のように表示されることがありました。(はい、html内に自動的に$ applyが使用され、変数は空ではありません。それは)

$scope.companyOptions = companyService.options 

である私は、このような$時計、$タイムアウト、約束、$ rootScopeなどを使用するなど、多くのソリューションを試してみましたが、どれも、私は値を取得し、すべてのコントローラとディレクティブで$ウォッチを使用する以外は働いていない:

$scope.$watch(function() { return companyService.options }, function (newVal) { 
    // checking if companyService.options is still empty or not 
    if (!$.isEmptyObject(newVal)) { 
    // Now the options is filled, do some stuff... 
    } 
}) 

私の質問は次のとおりです。

  1. すべてのコントローラで$ watchを使用しています。しかし、それはちょっと乱雑ですので、それらを取り除く方法はありますか?
  2. すべてのコントローラ/指令で$ watchを使用する代わりに、サービス内で一度使用できますか?
  3. 「オプション」が空の場合は、サービス内のhttpリクエストを呼び出す方が理にかなっていますか?私は約束を使うことができるように? (しかし、私はこのオプションを他の機能のために選択しない方が良いです。グローバルコントローラ内でcompanyOptionsを取得/設定する方が良いです)

答えて

0

多くのソリューションを試した後、私は以下のスーツを決定しました。私はそれが他の人にとって役に立つかもしれないことを願っています。

私は、サービスの代わりにngStorage(https://github.com/gsklee/ngStorage)で会社オプションを保持することに決めました。

は、これは:

companyService.setOptions($scope.companyOptions) 

これに変更:コードのこの作品は、「前に」動作するよう

$scope.$storage.companyOptions = $scope.companyOptions 

は、それから私は、次のコードの助けを借りて、グローバルなルート決意を使用しました実際のルーティングが発生します。 (私も、ユーザートークンが有効であるかどうかを確認するために、ここでHTTPリクエストを行うための工場がcheckTokenと呼ばれている):

Routes.config(['$routeProvider', function ($routeProvider) { 
    var originalWhen = $routeProvider.when 
    $routeProvider.when = function (path, route) { 
    route.resolve || (route.resolve = {}) 
    angular.extend(route.resolve, { 
     checkToken: ['$checkToken', function ($checkToken) { 
     return $checkToken.checkToken() 
     }] 
    }) 
    return originalWhen.call($routeProvider, path, route) 
    } 
}]) 

そして、これは私もsettedするcompanyOptionsを監視し、工場自体、です。そして、ページへのルート、それは準備ができている:

.factory('$checkToken', ['$q', '$timeout', '$location', '$api', '$rootScope', '$localStorage', function ($q, $timeout, $location, $api, $rootScope, $localStorage) { 
    return { 
    checkToken: function() { 
     var deferred = $q.defer() 
     $api('IsTokenValid', {}) 
     .then(function (response) { 
      // some unrelated codes here... 
      // watching companyoptions in localStorage 
      $rootScope.$watch(function() { return $localStorage.companyOptions }, function (newVal) { 
      if (!$.isEmptyObject(newVal)) { 
       // now that we have companyOptions, resolve and go to page 
       deferred.resolve('go to page!') 
      } 
      }, true) 
     }) 
     return deferred.promise 
    } 
    } 
}]) 

そして最後に、このソリューションのおかげで、私のコントローラでは、この:

$scope.$watch(function() { return companyService.options }, function (newVal) { 
    // checking if companyService.options is still empty or not 
    if (!$.isEmptyObject(newVal)) { 
    // Now the options is filled, do some stuff... 
    } 
}) 

はこの就任、そしてIはcompanyService工場を処分した:

$scope.companyOptions = $scope.$storage.companyOptions