使用 $resource.query,我想 return 一个包含实际资源数组的对象

Using $resource.query, I want to return an object that contains an array of the actual resource

默认情况下,$resource.query() 设置为期望成为 $resource 对象的对象数组。为了以一种很好的 restful 方式进行分页,我将我的 GET /api/widgets 端点设置为 return 以下对象:

{
  currentPage: 1,
  perPage: 20,
  totalItems: 10039,
  items: [{...}, {...}, {...}]
}

有没有办法让 angular 知道 items 属性 是要成为 $resource 对象的项目数组?

简单的方法是使用 $resouce.get,如果您想使用查询,您可以覆盖该行为。

$resource('/notes/:id', null,
{
    'query':  {method:'GET', isArray:false}
});

更多信息https://docs.angularjs.org/api/ngResource/service/$资源

您需要指定自己的自定义操作。

我想你的代码看起来像这样:

factory('Widget', function($resource) {
  return $resource('/api/widgets');
});

改成这样:

factory('Widget', function($resource) {
  return $resource(/api/widgets, null, {
    query: {
      method: 'GET',
      isArray: true,
      transformResponse: function(data) {
        return angular.fromJson(data).items;
      }
    }
  });
});

我刚遇到同样的问题,我想提出一个可以更好一点的解决方案:

factory('Widget', function($resource) {
    return $resource(/api/widgets, null, {
        query: {
            interceptor: {
                response: function(response) {
                    return response.data.items;
                }
            }
        }
    }
}

我认为它可能更好,因为您正在重用标准 angular 行为(实际上,它比 fromJson 做的多一点)并拦截输出结果以过滤您的内容想要。

我使用这种模式来查询分页信息。

module.config(function($resourceProvider){
    $resourceProvider.defaults.actions.query = {
        method: 'GET',
        interceptor: {
            response: function(response) {
                response.resource.$totalCount = response.data.totalCount;
                response.resource.$limit = response.data.limit;
                response.resource.$offset = response.data.offset;
                return response.resource;
            }
        },
        transformResponse: function(data, headers, status) {
            var out = angular.fromJson(data);
            out.data.totalCount = out.totalCount;
            out.data.limit = out.limit;
            out.data.offset = out.offset;
            return out.data;
        },
        isArray: true
    };
})