作者:zhoujinchen | 来源:互联网 | 2023-05-21 10:58
问题很简单:使用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
};
});
是的,我们可以注入$logProvider
,但它没有需要的方法(.log
,.error
等).
是的,我们可以注入$logProvider
,然后手动调用$logProvider.$get()
,但我们将无法使用装饰器的其他逻辑.
是的,我们可以编写自己的logProvider,但我想知道为什么Angular不支持这个开箱即用的功能.
那么,我们不能在提供者中以"真正的角度方式"使用控制台吗?这个事实很奇怪.而且伤心.
问题:我如何在提供商中以"真正的角度方式"使用控制台?
我无法找到这个问题的任何解释.Angular Developers Guide说我们需要在每个地方使用$ log而不是控制台.
1> PSL..:
提供者在创建任何服务之前运行得太早,或者换句话说,提供者的$ get是服务构造函数,并且在模块的配置阶段之后它被实例化(并且当通过依赖注入首次访问它时,注入器实例化构造函数和保持单身).并且提供程序在配置阶段期间或之前运行(因为提供程序方法用于config
在模块阶段配置服务).这意味着$ log服务尚不可用.
$logProvider.$get
将为您提供logservice的构造函数,您可以自己通过调用创建它的实例,$injector.instantiate($logProvider.$get)
但问题是它依赖于尚未实例化的窗口服务,因此最终您的logger实例化将失败.
所以我能想到的一种方法是从另一个喷射器获得$ log,即angular.injector(['ng']).get('$log')
.
即
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
或者另一种方法就是疯狂地实例化它,在这种情况下实例化它的依赖服务它只是$ 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
只是添加一个不同的注释:$log
在应用程序的配置阶段尝试访问服务时,您将看到相同的行为.但有时由于decorators
工作方式的原因,您仍然可以通过使用虚拟装饰器强制创建早期服务来利用它.
即:
.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
因此,最终的想法是,当您需要在实例化之前使用服务时,您需要通过解析所有依赖项等手动实例化它.