我试图从GitHub仓库中获取国家列表而不将所有信息存储在JS或我自己的API中,所以我写了一个一次性服务来处理这个问题。我将结果缓存在浏览器中,以防再次需要它们。但是,我注意到我写的方式,$http.get
被称为加载,而不是服务注入控制器 - 这意味着浏览器即使不需要,也会请求所有这些国家/地区数据(例如,即使用户访问国家/地区页面也是如此。
我构建这个的方式,因为服务只是返回一个承诺,我可以在控制器中调用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;
}]);
答案 0 :(得分: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
)then
演示。 http://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