【问题标题】:Two different implementation of module.provider() in AngularJSAngularJS 中 module.provider() 的两种不同实现
【发布时间】:2016-06-12 10:47:36
【问题描述】:

我是 Angular 的新手,我目前了解服务、工厂和提供商之间的区别。但是,在理解 module.provider() 函数时,我陷入了困境。有很多教程解释了 service、factory、provider 方法之间的区别。我读了很多,但是我没有找到任何教程解释 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/):

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

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

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

第二种情况,provider()方法中的this关键字和this.$get()方法中的this关键字分别指的是什么?

【问题讨论】:

    标签: javascript angularjs


    【解决方案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 对象。然后使用绑定到新创建的对象instance 的this 调用构造函数(Type)。现在,注意返回语句:

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

    回答您的问题:

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

    除此之外,当您使用angular.module().service 快捷方式定义服务时,您也可以同时使用这两种策略,因为在内部调用service 方法类似于注册以下提供程序:

    {
      $get: function() {
        return $injector.instantiate(constructor);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      相关资源
      最近更新 更多