在angular-js中编写懒惰ajax服务的最佳做法是什么?例如,我想创建资源,由于某种原因应该返回这样的承诺:
angular.module('MyModule',[])
.factory('myService', function() {
return {
getData: function() {
return $http.get('http://host/api/data');
}
}
});
我想只加载一次这样的数据,那么实现它的最佳方法是什么? 我只有一个想法,这真的很难看:
angular.module('MyModule', [])
.factory('myService', function($q) {
var dataResponse = null;
return {
getData: function() {
if (dataResponse) {
var def = $q.defer();
def.resolve(dataResponse);
return def.promise;
}
return $http.get('http://host/api/data');
},
setDataResponse: function(response) {
dataResponse = response;
}
}
})
.controller('MyCtrl', function($scope, myService) {
myService.getData().then(function(response) {
myService.setDataResponse(response);
$scope.data = response.data
})
});
我不喜欢这部分:
var def = $q.defer();
def.resolve(dataResponse);
return def.promise;
而且我不喜欢每次调用getter时都必须编写响应设置器的事实,但我真的不知道如何更好地编写代码。
答案 0 :(得分:2)
因为你不喜欢这个部分:
var def = $q.defer();
def.resolve(dataResponse);
return def.promise;
将其重写为:
return $q.resolve(dataResponse);
AngularJS< 1.4当()时调用resolve方法。
可以通过在' getData'中的服务内部缓存结果来修复其余代码。解决之前的方法。这不应该是来电者的责任。所以:
return {
getData: function() {
if (dataResponse !== null) {
return $q.resolve(dataResponse);
}
return $http.get('http://host/api/data').then(onSuccess);
function onSuccess(data){
dataResponse = data;
return data;
}
}
}
答案 1 :(得分:2)
您可以稍微清理一下记忆逻辑。
angular.module('MyModule', [])
.factory('myService', function($q) {
var dataResponse = null;
return {
getData: function() {
if (dataResponse) {
return $q.when(dataResponse); // or $q.resolve for angular 1.4+
}
return $http.get('http://host/api/data').then(function(data) {
dataResponse = data;
return data;
});
},
}
})
.controller('MyCtrl', function($scope, myService) {
// use as normal. No need to write back
myService.getData().then(function(response) {
$scope.data = response.data
})
});
答案 2 :(得分:0)
您应该使用$resource,这可以选择简单地缓存数据,并且更容易绑定到RESTapi。
否则你可以自己缓存数据:
angular.module('MyModule', [])
.factory('MyService', function($q) {
var dataResponse;
return {
getData: function() {
return $q(function(resolve, reject) {
if(angular.isDefined(dataResponse)) {
resolve(dataResponse);
} else {
$http
.get('http://host/api/data')
.then(function(response) {
dataResponse = response;
resolve(dataResponse);
});
}
});
if (dataResponse) {
var def = $q.defer();
def.resolve(dataResponse);
return def.promise;
}
return $http.get('http://host/api/data');
},
setDataResponse: function(response) {
dataResponse = response;
}
}
})
.controller('MyCtrl', function($scope, MyService) {
MyService
.getData()
.then(function(response) {
var vm = this;
vm.data = response.data
})
});
现在请注意,我将数据绑定到控制器(ViewModel的vm),因此您应该将模板重构为以下内容:
<ul ng-controller="MyCtrl as ctrl">
<li ng-repeat="item in ctrl.data">
{{ item.name }}: {{ item.price }}
</li>
</ul>