简体   繁体   English

AngularJS Provider依赖注入 - 在提供程序中使用$ log

[英]AngularJS Provider dependency injection - using $log in provider

The problem is simple: using AngularJS we can't inject $log into provider. 问题很简单:使用AngularJS我们不能将$ log注入提供者。

angular.module('my.module', [])
    .provider('myProvider', function ($log, $logProvider) {
        $log.log("Aloha!"); // Unknown provider: $log
        $logProvider.log("Hi!"); // undefined is not a function: $logProvider has no `log` method 
        this.$get = function($log) {
            $log.log("Hello!"); // Everything is ok here
        };
    });

Yes, we can inject $logProvider , but it has no needed methods( .log , .error , etc.). 是的,我们可以注入$logProvider ,但它没有所需的方法( .log.error等)。

Yes, we can inject $logProvider , and then manually call $logProvider.$get() , but we will unable to use additional logic from decorators. 是的,我们可以注入$logProvider ,然后手动调用$logProvider.$get() ,但我们将无法使用装饰器的其他逻辑。

Yes, we can write our own logProvider, but I wonder why Angular don't support this feature out-of-the-box. 是的,我们可以编写自己的logProvider,但我想知道为什么Angular不支持这个开箱即用的功能。

So, we can't use console in 'true angular way' in provider? 那么,我们不能在提供者中以“真正的角度方式”使用控制台吗? That fact is very strange. 这个事实很奇怪。 And sad. 而且伤心。

The question : how I need to use console in "true Angular way" in providers? 问题 :我如何在提供商中以“真正的角度方式”使用控制台?

I was unable to find any explanations of this problem. 我无法找到这个问题的任何解释。 Angular Developers Guide says that we need to use $log everywhere instead of console. Angular Developers Guide说我们需要在每个地方使用$ log而不是控制台。

Providers run too early before any services are created or in other words provider's $get is the service constructor and it gets instantiated after the config phase of the module (and when it is accessed for the first time via dependency injection the injector instantiates the constructor and keep it as singleton). 提供者在创建任何服务之前运行得太早,或者换句话说,提供者的$ get是服务构造函数,并且在模块的配置阶段之后它被实例化(并且当通过依赖注入首次访问它时,注入器实例化构造函数和保持单身)。 And providers run during or before the config phase (since the provider methods are used for configuring the service during the config phase of the module). 并且提供程序在配置阶段期间或之前运行(因为提供程序方法用于在模块的config阶段配置服务)。 Which means $log service is not available yet. 这意味着$ log服务尚不可用。

$logProvider.$get will give you the constructor for logservice, you could yourself create an instance of it by calling $injector.instantiate($logProvider.$get) but the problem is that it has a dependency on window service which has not bee instantiated yet, so ultimately your logger instantiation will fail. $logProvider.$get将为您提供logservice的构造函数,您可以通过调用$injector.instantiate($logProvider.$get)来创建它的实例,但问题是它依赖于窗口服务而不是蜜蜂实例化,所以最终你的记录器实例化将失败。

So one way i could just think of is to get $log from another injector, ie angular.injector(['ng']).get('$log') . 所以我能想到的一种方法是从另一个注入器获取$ log,即angular.injector(['ng']).get('$log')

ie

angular.module('my.module', [])
  .provider('myProvider', function ($log, $logProvider) {
    var $log =  angular.injector(['ng']).get('$log');
    $log.log("Aloha!"); 

    this.$get = function($log) {
        $log.log("Hello!"); // Everything is ok here
    };
});

Plnkr Plnkr

Or another way just go crazy instantiate it on your own, instantiating its dependent services in this case it is just the $window (or even provide global window object as locals). 或者另一种方法就是疯狂地实例化它,在这种情况下实例化它的依赖服务它只是$ window (甚至提供全局窗口对象作为本地)。

 .provider('myProvider', function ($logProvider,$injector, $windowProvider) {
    //get window service, if you want to really provide window service instance itself, or just provide the global window object
    var window = $injector.instantiate($windowProvider.$get);
    //Get log provider providing locals for $window
    var $log =  $injector.instantiate($logProvider.$get,{$window:window})

    $log.log("Aloha!");// Everything is ok here too

    this.$get = function($log) {
        $log.log("Hello!"); // Everything is ok here
    };

});

Plnkr Plnkr

Just to add a different note: You will see the same behavior while trying to access the $log service during the config phase of the app as well. 只是添加一个不同的注释:在应用程序的配置阶段尝试访问$log服务时,您将看到相同的行为。 But sometimes due to the way decorators work you could still make use of it by forcing an early service creation by using a dummy decorator. 但有时由于decorators工作的方式,你仍然可以通过使用虚拟装饰器强制创建早期服务来利用它。

ie: 即:

.config(function($provide){
   //Just a dummy decorator
   $provide.decorator('$log', function($delegate){
      return $delegate;
  });

}).config(function($logProvider){
   //get logger instance
   var log = $logProvider.$get();
   log.debug("Got it");
});

Plnkr Plnkr

So ultimately the idea is that, when you need to use a service before it has been instantiated yet, you would need to manually instantiate it by resolving all of its dependencies and so on. 因此,最终的想法是,当您需要在实例化之前使用服务时,您需要通过解析所有依赖项等手动实例化它。

You can write a wrapper service say logger which can have methods like log, warn, debug etc. and inject your logger service wherever required you can do the formatting there 您可以编写一个包装器服务说logger,它可以有日志,警告,调试等方法,并在需要时注入您的记录器服务,您可以在那里进行格式化

eg: Below method is inside my logger service to invoke this just inject logger and call log method. 例如:下面的方法是在我的记录器服务中调用它只是注入记录器和调用日志方法。

this.log = function () {
        if (this.debuggingEnabled) {
           for (var i = 1; i < arguments.length; i++) {
              $log.log("[" + $filter('date')(new Date(), this.format) + "] -- " + arguments[0] + " -- " + JSON.stringify(arguments[i]));
           }
        }
     };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Angular Provider中的依赖注入 - Dependency Injection into Angular Provider 未知提供者:membership ServiceProvider &lt; - membershipService &lt; - angularjs依赖注入中的membershipController错误 - Unknown provider: membershipServiceProvider <- membershipService <- membershipController error in angularjs Dependency Injection 在Angularjs项目中注入未知提供程序 - Injection of unknown provider in Angularjs Project AngularJS /依赖注入-如何在依赖提供程序数组中传递简单的字符串文字以用作值? - AngularJS/Dependency Injection - How do I pass in a simple string literal in the dependency provider array for consumption as a value? 未知提供程序错误,依赖注入,模态控制器 - Unknown Provider Error, Dependency Injection, Modal Controller 在AngularJs中使用依赖注入与Typescript - Using dependency injection with typescript in AngularJs NestJS 依赖注入错误:提供程序/模块不是当前处理模块的一部分 - NestJS Dependency Injection Error: provider/module is not part of currently processed module 如何在Angular中强制更新依赖项注入组件:NullInjectorError:没有ChangeDetectorRef的提供程序 - How to force update the dependency injection component in Angular: NullInjectorError: No provider for ChangeDetectorRef 角注入(未知的提供者) - Angular injection (unknown provider) angularJS中的状态提供者和路由提供者 - state provider and route provider in angularJS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM