[英]Best practices to write lazy ajax services
在angular-js中编写惰性Ajax服务的最佳实践是什么? 例如,我想要创建出于某种原因应该返回promise的资源:
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都必须编写响应设置器这一事实,但是我真的不知道如何使此代码更好。
由于您不喜欢这一部分:
var def = $q.defer();
def.resolve(dataResponse);
return def.promise;
将其重写为:
return $q.resolve(dataResponse);
并不是说在AngularJS <1.4中,resolve方法被称为when()。
您可以通过在解析前在“ 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;
}
}
}
您可以稍微整理一下记忆逻辑。
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
})
});
您应该使用$ 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的虚拟机),因此您应该将模板重构为以下形式:
<ul ng-controller="MyCtrl as ctrl">
<li ng-repeat="item in ctrl.data">
{{ item.name }}: {{ item.price }}
</li>
</ul>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.