当前位置: 首页 > 面试题库 >

Angular $ injector可以用$ provide.decorator装饰吗?

东郭存
2023-03-14
问题内容

也许这是一个可怕的主意,但如果是这样,请告诉我为什么,然后假装这是一项学术活动,不会在生产中日渐成熟。

我想在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;
    };
})();

具体错误是:

未捕获的错误:[$ injector:modulerr]由于以下原因而无法实例化模块应用程序:错误:[$ injector:unpr]未知提供程序:$
injectorProvider


问题答案:

您不能在$ injector上使用Angular装饰器服务。正如Artur所说,$injector它与其他服务有些不同。但是我们可以创建自己的装饰器。

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

代码级别,问题在于$injector没有构造函数-没有$injectorProvider

例如,这两个都返回true:

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

但是,虽然返回true:

$injector.has('$injector')

这将返回false:

$injector.has('$injectorProvider')

当我们查看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});
   };
}

providerSuffix = 'Provider'

因此,Angular装饰器希望在服务的构造函数(serviceName + providerSuffix)上进行操作。实用上,
由于没有$injectorProvider所以 不能使用decorator

我们可以做的是自己替换Angular注入器的get功能,方法是将注入器的默认值替换为get调用原始Angular定义的默认值,然后调用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;
    }
}]);

您会看到注入的提供程序是第一个扩充,因此会app.value('aValue', 'something');产生以下日志语句:

injector called  ["aValueProvider"]

演示小提琴



 类似资料:
  • 本文向大家介绍详解Angular 4.x Injector,包括了详解Angular 4.x Injector的使用技巧和注意事项,需要的朋友参考一下 在介绍 Angular Injector (注入器) 之前,我们先要了解 Dependency Injection,即依赖注入的概念。 依赖注入允许程序设计遵从依赖倒置原则 (简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户端与

  • 我试图理解decorator是如何工作的,我想知道一个修饰过的函数是否可以访问decorator的变量。例如,在下面的代码中,如何使f1能够访问localVariable?这可能吗?这是一种很好的做事方式吗?

  • 问题内容: 有时,我创建一个装饰器类,如下所示: IntelliJ可以自动为我创建此类吗? 问题答案: 更新// 我注意到IntelliJ具有用于生成委托方法的“生成”选项。创建一个新类: 然后标记myInterface,转到“菜单”>“代码”>“委托方法”,选择要包装的所有方法,仅此而已。 //更新结束 您可以尝试“重构”->“用委派替换继承”重构。这样就应该能够做到。我称之为“使用Alt +

  • 问题内容: 我在网站上有一些限制区域,我想为此指定装饰器。但是我想对每个包含在主urls.py中的对象执行一次操作,而不是对包含在urls.py中的每个单独的URL进行一次操作。 所以代替: /private/urls.py: 我会做一些事情: /urls.py 不幸的是,除了它不起作用。 问题答案: 这是可行的,实际上我为此找到了两个 片段。 解决方案1 棉花替代品的第一个片段,以及通话期间注入

  • 问题内容: 抱歉,这是一个非常广泛的问题。 以下代码是网络上某些内容的片段。我感兴趣的关键是从@protected开始的行- 我想知道这是做什么的以及它是如何做到的?在执行do_upload_ajax函数之前,似乎正在检查是否已登录有效用户。这似乎是进行用户身份验证的一种非常有效的方法。我不了解此@函数的机制- 有人可以引导我正确的方向来解释如何在现实世界中实现它吗?Python 3请回答。谢谢。

  • 问题内容: 我有一个带有装饰器的函数,我正在Python Mock库的帮助下进行测试。我想用一个仅调用函数的模拟“ bypass”装饰器代替真正的装饰器。 我不知道的是如何在真正的装饰器包装功能之前应用补丁。我在补丁目标上尝试了几种不同的变体,并对补丁和导入语句重新排序,但均未成功。有任何想法吗? 问题答案: 装饰器在函数定义时应用。对于大多数功能,这是模块加载时的时间。(在其他函数中定义的函数会