javascript - AngularJS 中 module.provider() 的两种不同实现

标签 javascript angularjs

我是 Angular 的新手,目前我了解服务、工厂和提供商之间的区别。然而,我在理解 module.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/):

enter image description here

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

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

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

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

最佳答案

让我们引用 angular.module().provider 方法的文档,该方法实际上是一个 $provide服务方法:

provider(name, provider);

If the provider parameter is a constructor (function) - a new instance of the provider will be created using $injector.instantiate(), then treated as object.

因此,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 是我们的提供者构造函数。

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

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

您的问题的答案:

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

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

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

关于javascript - AngularJS 中 module.provider() 的两种不同实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37773340/

相关文章:

javascript - 如何在我的网站中嵌入 ace 编辑器

javascript - 如何在 CSS 中使悬停动态化?

javascript - ul 中的交换列表和事件元素位置保持不变

javascript - 在页面加载上运行 Angular 脚本

javascript - 正则表达式提取所有重复字符

javascript - 如何在 ReactJS 的功能组件中声明一个变量

javascript - 稍后以 Angular 引用元素

javascript - 为什么我的 Firebase 项目无需指定 apiKey 即可运行?

javascript - 过滤传递给指令的数据抛出异常

angularjs - 包装 ng-repeat