5

我有一个名为 的服务$doggedHttp,它公开与$http. 现在我想创建一个$doggedResource服务,它是 Angular$resource服务$doggedHttp而不是$http. 换句话说,我想$doggedHttp作为$http服务注入。

此外,在我的应用程序中,我希望能够同时创建$doggedResource$resource. 因此,我不能简单地$http$doggedHttp.

我认为依赖注入应该使这种情况易于解决。我错了吗 ?

相反,我不得不深入研究角度源代码,最终想出了一个非常丑陋的解决方案:

angular.module('doggedResource', ['ngResource', 'doggedHttp'])
  .config(function() {
    var ngResource = angular.module('ngResource'),
        doggedResource = angular.module('doggedResource');

    // replace the placeholder below with the $resource factory from ngResource
    doggedResource._invokeQueue[1][2][1][2] = ngResource._invokeQueue[0][2][1][2];
})
.factory('$doggedResource', ['$doggedHttp', '$parse', null /* this is just a placeholder */]);

有更好的解决方案吗?


备注我们不能$provide.decorator用来替换注入的$http服务。为了说明这个问题,这里是angular-resource.js的相关部分:

angular.module('ngResource', ['ng']).
  factory('$resource', ['$http', '$parse', function($http, $parse) {

    function ResourceFactory(url, paramDefaults, actions) {
    }

    return ResourceFactory;
  }

查看上面的代码,$provide.decorator回调将作为参数传递给 ResourceFactory。那时,依赖关系$http已经解决。而且由于 ResourceFactory$http在闭包内使用,我们无法更改它。

.config(function($provide) {
  $provide.decorator( '$resource', [ "$delegate", function( $delegate ) {
    // here $delegate is the ResourceFactory which has 
    // already been linked to `$http` by a closure.
  }
}
4

1 回答 1

1

您可能应该$doggedHttp在装饰器中编写所有逻辑$http。一旦你装修$http好了,一切都会好起来的

编辑:更正条件。

.config(function($provide) {
  $provide.decorator( '$http', [ "$delegate", function( $delegate ) {
    // here $delegate is the $http function.
    function $doggedHttp(config){
        //write your storage logic here.

        // route all the $http calls through $delegate at the end... 
        return $delegate(config);
    }
    //dont forget to create shortcut method overrides.
    //createShortMethods('get', 'delete', 'head', 'jsonp');
    //createShortMethodsWithData('post', 'put');

    // This is the simplest solution to what you wish to do..
    if( condition ) {
         return $doggedHttp; 
    }
    else { 
         return $delegate;
    }     

    //finally return the $doggedHttp ( and not the $delegate ) 

  }
}

或者,您可以将所有存储逻辑写入request interceptor- 您也可以在其中注入任何内容,因此也可以在该阶段存储您的调用和重新请求。

于 2013-10-14T16:37:00.280 回答