问题 AngularJS:使用自定义服务转换$ resource中的响应


我试图使用来自自定义服务的数据从角度$ 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);});

但我宁愿在服务中做装饰。我怎样才能做到这一点?


5347
2018-02-21 07:18


起源

是吗? transformResponse 函数被调用?您使用的是什么版本的Angular?您将在此处找到实现响应修饰的简约示例: jsfiddle.net/YxTNL/1 - Lukas Bünger
@LukasBünger感谢您的回复。我想出了一个解决方案并将其发布到 jsfiddle.net/maddin/7zgz6  在transformResponse中我无法实现的目标。我想我写了一个正确的答案...... - Maddin


答案:


不可能使用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
  };
});

8
2018-02-26 11:50





嗯,它实际上可以异步装饰资源的数据,但不能用 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;
});

7
2017-09-04 09:06



“打破一些资源概念”太糟糕了! $资源很糟糕。感谢您提供有用的信息! - Carl G