AngularJS: $resource 中的拦截器问题

AngularJS: Issue with interceptors in $resource

我有一个奇怪的行为,即使用自定义拦截器通过 $resource 操纵响应。

如果我使用这样的响应拦截器:

angular.module( 'app.services', [] )
  .factory( 'Product', function( $resource, routesConfig ) {
      return $resource( routesConfig.catalogueEndPointg(), {}, { 
        query: { 
          method :'GET', 
          isArray : false, 
          params : { 
            page : '@currentPage'
          },
          interceptor: {
            response: function( response ) {
              // DO STUFF
              return response;
            }
          },
        } 
      });
    });

然后,从我的控制器:

angular.module( 'app.controllers', [])
  .controller( 'DummyController', function( $scope, Product ){
    productsPromise.$promise
      .then(
        // Success
        function ( response ) {
          console.log( response );
        });
  }); 

此时,这是 console.log( 响应 ) 的输出:

在响应对象上,我有数据对象,正如预期的那样,但我也有这个资源:资源对象,它也再次包含响应数据。

但是,如果我根本不使用拦截器;我得到了预期的回应:

我不理解这种行为,我担心性能或内存问题。

有人可以澄清一下吗?

PS: 我需要使用拦截器,因为我必须修改服务器的响应。

不知道这种行为的原因。

ngResource 是故意这样做的。

摘自 github 问题 -> 由 gkalpak 回答 -> answer


默认拦截器不会添加任何 属性(属性 已经存在,由 ngResource 添加,原因我稍后会解释)。拦截器所做的只是 return response.resource 而不是 responseresponse.data.

如何 ngResource "works":

考虑以下代码:

var User = $resource(...);
var userInstance = User.get({id: 1});
// Request still pending | `userInstance` is an instance of `User`
// ...
// Response arrived | `userInstance` updated with new fields (from `response.data`)

基本上,当您创建资源实例时,User.get()(或您使用的任何方法)returns 一个对象(或一个数组,如果 isArray: true),它是一个实例User$resource 保留此 returned userInstance 的引用,因此它可以在响应到达后立即用更多属性填充它(基本上,它将扩展 userInstanceresponse.data).


为什么 ngResource 这样做

这是 ngResource 的一个非常方便的功能,它允许您在检索需要在视图中显示的数据时避免一些样板。比较以下片段:

<!-- In the view -->
Current user: {{ user.username }} &lt;{{ user.email }}&gt;

// Now, you can do this:
$scope.user = User.get({id: 1});

// You DON'T need to do this:
User.get({id: 1}).$promise.then(function (user) {
  $scope.user = user;
});

为什么不直接returnresource

那么,为什么 returning response.resource 依赖默认拦截器?为什么不直接将 $resource return resource 放在第一个位置(而不是将其附加到 response)? 这是为了允许您使用自定义拦截器,这些拦截器确实可以访问其他与响应相关的数据(例如 headersstatus 等),同时仍然只能 returning resource如果您选择不使用自定义拦截器。


PS:留在这里是为了提供答案。也许有人会检查这个。