也许这是一个可怕的想法,但如果是,那么请告诉我为什么然后假装这是一个学术练习,不会在生产中看到光明.
我想为Angular $ injector服务添加一些逻辑,以监视何时将某些服务注入其他服务.由于Angular似乎提供了一种装饰服务的机制,我认为这将是一种方法.但是,以下代码引发错误.
(function () {
'use strict';
var app = angular.module('app');
app.config(['$provide', function ($provide) {
$provide.decorator('$injector', ['$log', '$delegate', addLoggingToInjector]);
}]);
function addLoggingToInjector($log, $delegate) {
var baseInstantiate = $delegate.instantiate;
var baseInvoke = $delegate.invoke;
$delegate.instantiate = function (type, locals) {
// $log.debug('Calling $injector.instantiate');
baseInstantiate(type, locals);
};
$delegate.invoke = function (fn, self, locals) {
// $log.debug('Calling $injector.invoke');
baseInvoke(fn, self, locals);
};
return $delegate;
};
})();
Run Code Online (Sandbox Code Playgroud)
具体错误是:
未捕获错误:[$ injector:modulerr]由于以下原因无法实例化模块应用程序:错误:[$ injector:unpr]未知提供程序:$ injectorProvider
art*_*iak 13
答案是不.
$provide.decorator
用于拦截服务创建 - 这就是为什么它从.config
块调用,当仍有时间配置所有服务时,因为它们都没有创建.$provide.decorator
基本上得到了Provider
服务,并$get
与新交付的交换decorFn
.
$injector
不像其他服务.它创建,如在第一个步骤bootstrapping
的应用-的方式之前app.config
被调用.[看看函数:bootstrap
和createInjector
角度源代码]
但是,嘿,你可以通过稍微调整源代码很容易实现你的目标:-)特别注意function invoke(fn, self, locals)
.
更新我从@KayakDave获得了一些灵感.实际上你不必深入挖掘源代码本身.您可以使用以下模式来观察对任何$injector
方法的每次调用:
app.config(['$injector', function ($injector) {
$injector.proper =
{
get : $injector.get,
invoke : $injector.invoke,
instantiate : $injector.instantiate,
annotate : $injector.annotate,
has : $injector.has
}
function getDecorator(serviceName)
{
console.log("injector GET: ", serviceName);
return this.proper.get(serviceName);
}
function invokeDecorator(fn, self, locals)
{
console.log("injector INVOKE: ", fn, self, locals);
return this.proper.invoke(fn, self, locals);
}
function instantiateDecorator(Type, locals)
{
console.log("injector INSTANTIATE: ", Type, locals);
return this.proper.instantiate(Type, locals);
}
function annotateDecorator (fn)
{
console.log("injector ANNOTATE: ", fn);
return this.proper.annotate(fn);
}
function hasDecorator(name)
{
console.log("injector HAS: ", name);
return this.proper.has(name);
}
$injector.get = getDecorator;
$injector.invoke = invokeDecorator;
$injector.instantiate = instantiateDecorator;
$injector.annotate = annotateDecorator;
$injector.has = hasDecorator;
}]);
Run Code Online (Sandbox Code Playgroud)
Kay*_*ave 12
您不能在$ injector上使用Angular装饰器服务.正如Artur所说,$injector
与其他服务有点不同.但我们可以创建自己的装饰器.
在代码级别,问题是$injector
没有构造函数 - 没有$injectorProvider
.
例如,这两个都返回true:
$injector.has('$location');
$injector.has('$locationProvider')
Run Code Online (Sandbox Code Playgroud)
但是,这会返回true:
$injector.has('$injector')
Run Code Online (Sandbox Code Playgroud)
这返回false:
$injector.has('$injectorProvider')
Run Code Online (Sandbox Code Playgroud)
当我们查看Angular装饰器函数时,我们看到了重要性:
function decorator(serviceName, decorFn) {
var origProvider = providerInjector.get(serviceName + providerSuffix),
orig$get = origProvider.$get;
origProvider.$get = function() {
var origInstance = instanceInjector.invoke(orig$get, origProvider);
return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});
};
}
Run Code Online (Sandbox Code Playgroud)
和
providerSuffix = 'Provider'
Run Code Online (Sandbox Code Playgroud)
所以Angular装饰器期望在服务的构造函数(serviceName + providerSuffix
)上运行.实际上$injectorProvider
,因为我们没有一个我们不能使用装饰器.
我们所能做的是覆盖角度喷射的get
功能,通过更换喷油器的默认自己get
与一个调用原始,角定义,get
其次是我们的职责.
我们将这应用于$injector
而不是不存在,$injectorProvider
如下所示:
app.config(['$provide','$injector', function ($provide,$injector) {
// The function we'll add to the injector
myFunc = function () {
console.log("injector called ", arguments);
};
// Get a copy of the injector's get function
var origProvider = $injector,
origGet = origProvider.get;
//Override injector's get with our own
origProvider.get = function() {
// Call the original get function
var returnValue = origGet.apply(this, arguments);
// Call our function
myFunc.apply(this,arguments);
return returnValue;
}
}]);
Run Code Online (Sandbox Code Playgroud)
您将看到正在注入的提供程序是第一个扩充,因此app.value('aValue', 'something');
产生以下日志语句:
injector called ["aValueProvider"]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7143 次 |
最近记录: |