2014-10-20 58 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

    答案