javascript AngularJS:使用自定义服务在 $resource 中转换响应
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21927819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS: transform response in $resource using a custom service
提问by Maddin
I am trying to decorate the returned data from a angular $resource with data from a custom service. My code is:
我正在尝试使用来自自定义服务的数据装饰从 angular $resource 返回的数据。我的代码是:
angular.module('yoApp')
.service('ServerStatus', ['$resource', 'ServerConfig', function($resource, ServerConfig) {
var mixinConfig = function(data, ServerConfig) {
for ( var i = 0; i < data.servers.length; i++) {
var cfg = ServerConfig.get({server: data.servers[i].name});
if (cfg) {
data.servers[i].cfg = cfg;
}
}
return data;
};
return $resource('/service/server/:server', {server: '@server'}, {
query: {
method: 'GET',
isArray: true,
transformResponse: function(data, header) {
return mixinConfig(angular.fromJson(data), ServerConfig);
}
},
get: {
method: 'GET',
isArray: false,
transformResponse: function(data, header) {
var cfg = ServerConfig.get({server: 'localhost'});
return mixinConfig(angular.fromJson(data), ServerConfig);
}
}
});
}]);
It seems I am doing something wrong concerning dependency injection. The data returned from the ServerConfig.get() is marked as unresolved. I got this working in a controller where I do the transformation with
似乎我在依赖注入方面做错了什么。从 ServerConfig.get() 返回的数据被标记为未解析。我在控制器中使用它进行了转换
ServerStatus.get(function(data) {$scope.mixinConfig(data);});
But I would rather do the decoration in the service. How can I make this work?
但我宁愿在服务中做装饰。我怎样才能使这项工作?
采纳答案by Maddin
It is not possible to use the transformResponse to decorate the data with data from an asynchronous service. I posted the solution to http://jsfiddle.net/maddin/7zgz6/.
不可能使用 transformResponse 用来自异步服务的数据装饰数据。我将解决方案发布到http://jsfiddle.net/maddin/7zgz6/。
Here is the pseudo-code explaining the solution:
这是解释解决方案的伪代码:
angular.module('myApp').service('MyService', function($q, $resource) {
var getResult = function() {
var fullResult = $q.defer();
$resource('url').get().$promise.then(function(data) {
var partialPromises = [];
for (var i = 0; i < data.elements.length; i++) {
var ires = $q.defer();
partialPromisses.push(ires);
$resource('url2').get().$promise.then(function(data2) {
//do whatever you want with data
ires.resolve(data2);
});
$q.all(partialPromisses).then(function() {
fullResult.resolve(data);
});
return fullResult.promise; // or just fullResult
}
});
};
return {
getResult: getResult
};
});
回答by Angel Yordanov
Well, Its actually possible to decorate the data for a resource asynchronously but not with the transformResponse
method. An interceptor
should be used.
嗯,实际上可以异步装饰资源的数据,但不能使用transformResponse
方法。一个interceptor
应该被使用。
Here's a quick sample.
这是一个快速示例。
angular.module('app').factory('myResource', function ($resource, $http) {
return $resource('api/myresource', {}, {
get: {
method: 'GET',
interceptor: {
response: function (response) {
var originalData = response.data;
return $http({
method: 'GET',
url: 'api/otherresource'
})
.then(function (response) {
//modify the data of myResource with the data from the second request
originalData.otherResource = response.data;
return originalData;
});
}
}
});
You can use any service/resource instead of $http
.
您可以使用任何服务/资源而不是$http
.
Update:
Due to the way angular's $resource interceptor is implemented the code above will only decorate the data returned by the $promise and in a way breaks some of the $resource concepts, this in particular.
更新:
由于 angular 的 $resource 拦截器的实现方式,上面的代码只会修饰 $promise 返回的数据,并在某种程度上打破了一些 $resource 概念,尤其是这一点。
var myObject = myResource.get(myId);
Only this will work.
只有这样才能奏效。
var myObject;
myResource.get(myId).$promise.then(function (res) {
myObject = res;
});