问题描述
我在我的应用程序一个基本的工厂处理API调用。目前我使用的格式为:
I have a basic factory in my app that handles API calls. Currently I'm using the form:
.factory('apiFactory', function($http){
var url = 'http://192.168.22.8:8001/api/v1/';
return {
getReports: function() {
return $http.get(url+'reports').then(function(result) {
return result;
});
},
getReport: function(id) {
return $http.get(url+'report/'+id).then(function(result) {
return result;
});
}
}
})
在我的控制,我处理,像这样的承诺:
And in my controller I'm handling the promise like so:
.controller('exampleController', function($scope, apiFactory) {
apiFactory.getReports().then(
function(answer) {
if (answer.status==200){
if (answer.data.status == "error"){
// DISPLAY ERROR MESSAGE
console.log(answer.data.msg);
}
} else{
// THROW error
console.log('error: ', answer);
}
},
function(error){
console.log('error: ', answer);
}
);
}
}
})
看来我可以承诺处理移动到我的工厂,而不是在我的控制器做的,但我不知道这会有什么好处比别人更小的控制器。
It seems I could move the promise handling to my Factory instead of doing it in my controller, but I'm not sure if that would have any benefits others than a smaller controller.
可能有人对这种模式解释最佳实践?
Could somebody explain the best practices regarding this pattern?
推荐答案
这最终取决于你想要多少数据提供给服务调用者。如果需要,你可以肯定的HTTP响应对象返回给调用者,并让他们处理响应(其中,顺便说一句,总是HTTP 2XX,如果承诺得到解决,而不是拒绝)。
It is ultimately up to you how much data you want to provide to the caller of the service. If needed, you could definitely return the HTTP response object to the caller, and have them process the response (which, btw, is always HTTP 2xx, if the promise is resolved rather than rejected).
但是,如果你想从数据如何到达那里的具体来电隔离(也许它被缓存,或通过其它机制提供的),如果你需要进行后处理的数据,那么最好是处理在服务的响应。
But if you want to isolate the caller from the specifics of how the data got there (maybe it was cached, or supplied via another mechanism), and if you need to post-process the data, then it is advisable to handle the response in the service.
下面是一个例子:
.factory("apiService", function($http, $q){
var url = 'http://192.168.22.8:8001/api/v1/';
return {
getReports: function() {
return $http.get(url+'reports').then(function(result) {
var data = result.data;
if (data === "something I don't accept"){
return $q.reject("Invalid data");
}
var processedData = processData(data);
return processedData;
})
.catch(function(err){
// for example, "re-throw" to "hide" HTTP specifics
return $q.reject("Data not available");
})
},
// same idea for getReport
}
});
然后,控制器就不需要关心底层机制 - 所有它得到的数据或拒绝
Then the controller wouldn't need to care about the underlying mechanism - all it gets is data or a rejection.
.controller('exampleController', function($scope, apiService) {
apiService.getReports()
.then(function(reports){
$scope.reports = reports; // actual reports data
});
})
题外话:
注意我是如何从apiFactory
更改服务的名称apiService
。我想指出这一点以消除可能的误解。无论您使用 .factory
或。服务
或 .value的
你得到的注射什么东西是一个的服务的实例。 .factory
仅仅是一个机制的如何的此服务被实例化,所以这个名字apiFactory
是用词不当。这里唯一的工厂是你与 .factory
注册功能(可以是匿名的,当然):
Notice how I changed the name of the service from "apiFactory"
to "apiService"
. I wanted to point that out to remove a possible misconception. Whether you use .factory
or .service
or .value
what you get as an injectable is always a service instance. .factory
is just a mechanism of how this service is instantiated, so the name "apiFactory"
is a misnomer. The only "factory" here is a function that you register with .factory
(which could be anonymous, of course):
.factory("fooSvc", function fooSvcFactory(){
return {
getFoo: function(){...}
}
})
这篇关于角最佳实践:在工厂或在控制器中的承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!