2014-10-20 61 views
0

我試圖從GitHub倉庫中獲取國家列表,但沒有將所有信息存儲在JS或我自己的API中,因此我編寫了一次性服務來照顧這對我來說,並緩存在瀏覽器中的結果,以防他們再次需要。然而,我注意到我寫的方式,$http.get被稱爲負載而不是服務注入到控制器 - 這意味着即使不需要瀏覽器請求所有國家的數據(例如,即使當用戶訪問國家頁面時AngularJS服務延遲API調用

由於服務只是返回一個承諾,所以我可以在控制器中調用countrylist.then(...)。有沒有辦法保持這一點,但仍然延遲直到它的實際需要Github的請求之下

代碼:

angular.module('myModule') 
    .factory('countrylist', ['$http', 'growl', '$q', function ($http, growl, $q) { 

     var deferred = $q.defer(); 
     var flagUrl = "https://raw.githubusercontent.com/hjnilsson/country-flags/master/png250px/{}.png"; 

     $http.get('https://raw.githubusercontent.com/lukes/ISO-3166-Countries-with-Regional-Codes/master/slim-2/slim-2.json', 
       {cache: true}) 
       .success(function (data) { 
        angular.forEach(data, function (item) { 
         item.flag = flagUrl.replace("{}", item['alpha-2'].toLowerCase()); 
        }); 

        deferred.resolve(data); 
       }).error(function (data) { 
        growl.warn("Error loading country data"); 
        deferred.reject(); 
       }); 

     return deferred.promise; 

    }]); 

回答

1

一旦工廠被注入到任何控制器中,工廠中的所有內容都會立即運行,這會在您的應用程序啓動時發生。

要做到這一點的唯一方法是使用提取數據的方法從工廠返回對象。

angular.module('myModule') 
.factory('countrylist', ['$http', 'growl', '$q', function ($http, growl, $q) { 
    return { 
    fetch: function() { 
     var deferred = $q.defer(); 
     var flagUrl = "https://raw.githubusercontent.com/hjnilsson/country-flags/master/png250px/{}.png"; 

     $http.get('https://raw.githubusercontent.com/lukes/ISO-3166-Countries-with-Regional-Codes/master/slim-2/slim-2.json', 
      {cache: true}) 
      .success(function (data) { 
       angular.forEach(data, function (item) { 
        item.flag = flagUrl.replace("{}", item['alpha-2'].toLowerCase()); 
       }); 

       deferred.resolve(data); 
      }).error(function (data) { 
       growl.warn("Error loading country data"); 
       deferred.reject(); 
      }); 

     return deferred.promise; 
    } 
    }; 
}]); 

然後在你的控制器,你顯然需要做

countryList.fetch().then(...) 
1

讓它變得簡單。它是那樣簡單

  1. 返回promise在你的服務(沒有必要的服務,用then)在你的控制器

演示

  • 使用thenhttp://plnkr.co/edit/cbdG5p?p=preview

    var app = angular.module('plunker', []); 
    
    app.service('myService', function($http) { 
        return { 
        async: function() { 
         return $http.get('test.json'); //1. this returns promise 
        } 
        }; 
    }); 
    
    app.controller('MainCtrl', function(myService,$scope) { 
        myService.async().then(function(d) { //2. so you can use .then() 
        $scope.data = d; 
        }); 
    }); 
    

    這是我的複製/粘貼從 Processing $http response in service

    答案