【问题标题】:Decorate Angular's $log to use a service that uses $http装饰 Angular 的 $log 以使用使用 $http 的服务
【发布时间】:2015-09-03 01:57:02
【问题描述】:

我正在尝试扩展$log 服务,以便它也向服务器发送消息。由于$http 使用$log,我收到来自Angular“找到循环依赖项”的错误。

app.js:

angular.module("app").config(function($provide) {
    $provide.decorator("$log", function($delegate, NodeLogger) {
        var logFn = $delegate.log;
        $delegate.log = function(message) {
            NodeLogger.log(message);
            logFn.apply(null, arguments);
        };
    });
});

NodeLogger.js:

angular.module("app").factory("NodeLogger", function($http) {

    function log(type, message) {
        var logMessage = type + ":" + message;
        $http.post("http://localhost:3000/log", "message=" + logMessage);
    }

    return {
        log: log
    }
});

我尝试在app.js 中使用$injector 来加载$http 并发出POST 请求,但它给出了同样的错误。有没有办法解决这个问题?我可以避免使用$http/$resource吗?

谢谢!

【问题讨论】:

  • 不要直接使用service或者factory,而是使用injector。

标签: angularjs http logging decorator


【解决方案1】:

$http 已经注入$log 并通过注入您的工厂NodeLogger 进而注入$http 来装饰它时,这是循环依赖的常见问题,您正在创建循环依赖。不是直接注入你的工厂,而是从注入器中获取工厂,另一种方法是在你的工厂中注入$injector,并从注入器中获取$http实例,而不是直接注入$http。这样可以避免工厂创建期间的循环依赖。一个重要的注意事项是返回$delegate,否则$log 服务将不会保存任何实例。

$provide.decorator("$log", function($delegate, $injector) {
    var logFn = $delegate.log;
    $delegate.log = function(message) {

      //Get NodeLogger factory instance from injector
      var NodeLogger = $injector.get('NodeLogger');
      NodeLogger.log(message);
      logFn.apply(null, arguments);
    };
    //Return the delegate
    return $delegate;
  });

angular.module("app", []).factory("NodeLogger", function($http) {

  function log(type, message) {
    var logMessage = type + ":" + message;
    $http.post("http://localhost:3000/log", "message=" + logMessage);
  }

  return {
    log: log
  }
}).config(function($provide) {
  $provide.decorator("$log", function($delegate, $injector) {
    var logFn = $delegate.log;
    $delegate.log = function(message) {
      var NodeLogger = $injector.get('NodeLogger');
      NodeLogger.log(message);
      logFn.apply(null, arguments);
    };
    return $delegate;
  });
}).run(function($log) {
  $log.log("Hey");
});;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>

<div ng-app="app"></div>

【讨论】:

  • 谢谢!这为我解决了问题:)
  • 如果这不起作用,请确保您没有像我一样将 $injector.get() 代码放在设置为 $delegate.log 的匿名函数之外!在这种情况下,你仍然有循环依赖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
  • 2015-01-31
  • 1970-01-01
相关资源
最近更新 更多