设置:我希望有一个服务,多个控制器可以查询使用$http提取的数据.最初的解决方案是使用建议
here的承诺.
问题:每次控制器查询服务时,服务都会返回$http承诺,导致多次查询只是从远程服务器中反复提取相同的数据.
解决方案:服务函数返回数据或下面的承诺.并由控制器进行相应的检查和操作.
app.factory('myService',function($http) { var items = []; var myService = { getItems: function() { // if items has content,return items; otherwise,return promise. if (items.length > 0) { return items; } else { var promise = $http.get('test.json').then(function (response) { // fill up items with result,so next query just returns items. for(var i=0;i<response.data.length;i++){ items.push(response.data[i]); } return items; }); // Return the promise to the controller return promise; } }; return myService; });
因此,当控制器需要该数据时,控制器只需执行以下操作:
app.controller('MainCtrl',function( myService,$scope) { var promiSEOrData = myService.async(); // Check whether result is a promise or data. if ( typeof promiSEOrData.then === 'function'){ // It's a promise. Use then(). promiSEOrData.then( function(data ){ $scope.data = data; }); } else { // It's data. $scope.data = data; } });
所以问题是:有没有更好的方法呢?对于许多控制器,这种方法会有很多重复的代码.理想情况下,控制器只是直接向服务查询数据.
谢谢!
$http返回一个promise,我们可以使用它而不是用$q创建一个新的.一旦承诺得到解决,我们就可以继续回复.
.factory('myService',['$http','$q',function($http,$q) { var items = []; var last_request_Failed = true; var promise = undefined; return { getItems: function() { if(!promise || last_request_Failed) { promise = $http.get('test.json').then( function(response) { last_request_Failed = false; items = response.data; return items; },function(response) { // error last_request_Failed = true; return $q.reject(response); }); } return promise; },}; }])
在你的控制器中:
myService.getItems().then( function(data) { $scope.data = data; } );