AngularJS中的module.provider()的两个不同实现

时间:2016-06-12 10:47:36

标签: javascript angularjs

我是Angular的新手,我目前了解服务,工厂和提供商之间的差异。但是,我在理解module.provider()函数时遇到了困难。有很多教程可以解释服务,工厂,提供者方法之间的差异。我读了很多,但是我没有详细找到任何教程explainig module.provide()方法,没有找到任何一起提到这两种不同方法的教程。

我从文档中读到提供者是可配置的工厂。以下是一个示例(http://blog.xebia.com/differences-between-providers-in-angularjs/):

var app = angular.module('app', []);
app.provider('movie', function () 
{
    var version;
    return {
        setVersion: function (value) {
            version = value;
        },
        $get: function () {
            return {
                title: 'The Matrix' + ' ' + version
            }
        }
    }
});
app.config(function (movieProvider) {
    movieProvider.setVersion('Reloaded');
});

继续研究module.provider()之后,我发现了一个不同的实现。以下是示例(http://tylermcginnis.com/angularjs-factory-vs-service-vs-provider/):

enter image description here

我想了解这些背后的逻辑,而不是记住。在第一个示例中,提供者看起来像工厂。它返回一个包含$ get()方法的对象。我从中理解,调用了提供者函数,并在需要时返回像工厂这样的对象。

在第二个中,它看起来像一个服务,因为使用此关键字设置了名为thingFromConfig和$ get()方法的属性。我从中理解,使用new关键字调用提供者函数,并在需要时返回一个像服务这样的对象。

哪一个是正确的?我们如何理解module.provide()的两种不同实现?

在第二种情况下,provider()方法中的this关键字和此。$ get()方法中的this关键字分别引用了什么?

1 个答案:

答案 0 :(得分:1)

让我们参考angular.module().provider方法的文档,这实际上是$provide服务的方法:

  

提供商(名称,提供商);

     

如果 provider 参数是构造函数(函数) - 将使用$injector.instantiate()创建提供程序的新实例,然后将其视为对象。

因此,provider方法的第二个参数是用于创建提供程序实例的构造函数(具有$get方法的对象)。现在,让我们看一下实例化过程,这里是$injector.instantiate()方法的来源:

function instantiate(Type, locals, serviceName) {
  var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype || null);
  var returnedValue = invoke(Type, instance, locals, serviceName);

  return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance;
}

其中Type是我们的提供者构造函数。

首先,使用构造函数的原型创建instance对象。然后调用构造函数(Type),并将this绑定到新创建的对象instance。现在,请注意return语句:

  • 如果构造函数返回object(您的第一个示例) - 它将作为提供程序实例返回。
  • 如果构造函数没有返回任何内容(第二个示例) - 新对象(instance,控制器运行它)将作为提供程序实例返回。

您的问题的答案:

  • 两种方式都是正确的;
  • 区别在于如何创建提供程序:在第一种情况下,您从构造函数显式返回提供程序实例,在第二种情况下,它创建为新的Object,然后使用{运行构造函数{1}}绑定到此新this;
  • 提供者构造函数中的Object对象最终将在整个应用程序中用作提供者实例(仅当构造函数未明确返回对象时);
  • this函数中的this对象是相同的东西 - 提供者实例的引用,当您第一次将服务注入到某处时$get函数将被调用{ {1}}绑定到提供程序实例,任何$get返回都将作为您的服务注入整个应用程序。

除此之外,当您使用this快捷方式定义服务时,您也可以同时使用这两种策略,因为内部调用$get方法类似于注册以下提供程序: / p>

angular.module().service