AngularJS将工厂注入提供者

时间:2015-11-17 01:20:52

标签: javascript angularjs

我正在构建一个必须使用provider配方的模块,因为它需要在运行时之前进行配置。我对模块化代码很感兴趣,所以我想向提供者注入一些服务。我知道将providers注入其他providers很简单,但对于我想要实现的内容似乎有些过分,所以我想注入一个factory

根据我的理解,在运行时期间使用$injector使我们可以通过angular instanceCache方法访问createInternalInjector,该方法返回已实例化的服务。

在配置阶段使用$injector时,您可以访问保存未实例化服务的providerCache

我觉得这个假设必须是不正确的。在下面的代码中,$injector正在提供程序中使用,但是通过在应用程序运行阶段调用的函数。我希望能够访问instanceCache,但我只能通过providerCache方法访问$injector.get

_tudModule.factory('wfTabletUsageDataCache', [
        function () {
            return {
                addToLog: fn () { … }
            }
        }
])


_tudModule.provider('$tabletUsageData', [
    '$injector', function $tabletUsageDataProvider ($injector) {

    function getCacheFactory() {
       return $injector.get('wfTabletUsageDataCacheProvider').$get();
    }

    function logInteraction(state, buttonId) {
        getCacheFactory().addToLog();           // fn() called
    }
]);

$injectorprovider禁止访问instanceCache怎么办?即使在config阶段期间没有运行提供程序中的方法?

另外,我之前没有看到我使用$injector.get('wfTabletUsageDataCacheProvider').$get()的方法。虽然它有效,但这是一种实现这种功能的坏方法吗?

感谢任何方向。

2 个答案:

答案 0 :(得分:2)

在配置阶段,(config()阻止或提供商)您可以注入提供商常量,而不是工厂,服务或值。如果提供商对您来说太过分了,您可以使用常量。

这样的事情可以起作用

_tudModule.constant('wfTabletUsageDataCache', {
  addToLog: function () { ... }
});

_tudModule.provider('$tabletUsageData', [ 'wfTabletUsageDataCache',
  function (wfTabletUsageDataCache) {
     wfTabletUsageDataCache.addToLog(...)
  }
]);
  

在配置阶段使用$injector时,您可以访问保存未实例化服务的providerCache

看来你是对的,但这种用法没有记载,一般不鼓励。 $injector是一项服务,不应将其注入提供商。

  

另外,我之前没有看到我使用$injector.get('...').$get()的方法。

提供商是定义Angular服务的最低级别方式。可以使用.service()重写所有.factory().value().provider()定义。根据定义,当实例化提供程序时,它必须公开一个$get方法,该方法是可注入的并负责返回服务实例。

这就是你在这里看到的。您正在使用$injector.get(...)检索(并实例化)提供程序,然后使用$get()方法创建服务实例。但是,通常会在幕后发生,而$get()方法并不是手动调用的。

您实际上是在试图破解在运行阶段之前不允许实例化服务的限制。不建议这样做。

答案 1 :(得分:1)

你的假设是正确的。您错过的是服务提供商和服务实例有两种不同的注入器。一旦您将提供者注入器注入provider,即使在配置阶段之后它也会继续处理提供者。您也可以查看this answer以获得澄清。

使用$injector.get('someProvider').$get()将返回与instanceCache无关且不是单身的新服务实例。即

$injector.get('someProvider').$get() !== $injector.get('someProvider').$get();

$get背后没有魔法,它只是一个构造函数,并且注入器没有办法或理由来跟踪它的调用。

可以安全地使用当前代码factory代替provider。如果必须在config中配置提供程序,则所有与实例相关的代码都应转到$get(因为factory只是provider的单一$get的糖语法方法)。