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);
}
}
});
}]);
依存性注入に関して何か問題があるようです。 ServerConfig.get()から返されたデータは、未解決としてマークされます。私はこれをコントローラーで動作させ、そこで変換を行います
ServerStatus.get(function(data) {$scope.mixinConfig(data);});
しかし、私はむしろサービスで装飾をしたいと思います。どうすればこれを機能させることができますか?
TransformResponseを使用して、非同期サービスからのデータでデータを装飾することはできません。ソリューションを http://jsfiddle.net/maddin/7zgz6/ に投稿しました。
解決策を説明する擬似コードは次のとおりです。
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
};
});
実際には、リソースのデータを非同期で装飾することは可能ですが、transformResponse
メソッドを使用することはできません。 interceptor
を使用する必要があります。
これが簡単なサンプルです。
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;
});
}
}
});
$http
の代わりに任意のサービス/リソースを使用できます。
更新:
angularの$ resourceインターセプターの実装方法により、上記のコードは$ promiseによって返されるデータのみを装飾し、ある意味で$ resourceの概念の一部、特にこれを破ります。
var myObject = myResource.get(myId);
これだけが機能します。
var myObject;
myResource.get(myId).$promise.then(function (res) {
myObject = res;
});