anglejs – 角度$注射器可以用$provide.decorator装饰吗?

前端之家收集整理的这篇文章主要介绍了anglejs – 角度$注射器可以用$provide.decorator装饰吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
也许这是一个可怕的想法,但是如果是,那么请告诉我为什么,然后假装这是一个不会看到生产中的光的学术活动。

我想为Angular $ Injection服务添加一些逻辑,以监控某些服务是否注入其他服务。由于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,locals);
        };

        return $delegate;
    };
})();

具体的错误是:

Uncaught Error: [$injector:modulerr] Failed to instantiate module app
due to: Error: [$injector:unpr] Unknown provider: $injectorProvider

您不能在$注射器上使用Angular装饰器服务。由于Artur注释,注射器与其他服务有所不同。但是我们可以创建我们自己的装饰器。

为什么我们不能使用Angular的装饰器

代码级别的问题是,$ inject没有构造函数 – 没有$ injectProvider。

例如,这两个都返回true:

$injector.has('$location');
$injector.has('$locationProvider')

但是,尽管如此:

$injector.has('$injector')

这会返回false:

$injector.has('$injectorProvider')

当我们看看Angular decorator功能时,我们看到了重要性:

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

providerSuffix = 'Provider'

所以Angular装饰器期望在服务的构造函数(serviceName providerSuffix)上运行。实际上,由于我们没有一个$ injectProvider,我们不能使用装饰器。

我们可以做的是通过将注射器的默认值替换为调用原始角度的角度定义的角度来取代角度注射器的get function

我们将这个应用到$ injector而不是不存在的$ injectProvider像这样:

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

你会看到被注入的提供者是第一个扩充,所以app.value(‘aValue’,’something’);产生以下日志语句:

injector called  ["aValueProvider"]

Demo fiddle

猜你在找的Angularjs相关文章