装饰Angular的$ log以使用使用$ http的服务

时间:2015-09-03 01:57:03

标签: angularjs http logging decorator

我正在尝试扩展$log服务,以便它还向服务器发送消息。我从Angular" 发现循环依赖"由于$http使用$log

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
    }
});

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

谢谢!

1 个答案:

答案 0 :(得分:5)

$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>
&#13;
&#13;
&#13;