Angular JS 工厂 vs 服务 vs 提供者的例子

Angular JS factory vs service vs provider by example

我知道这个问题已经被提出并且已经给出了答案。但是我通过实际示例学得最好,并且遇到了我不完全理解的代码。

我指的是 Angular Strap,它是一组很棒的用户交互指令: http://mgcrea.github.io/angular-strap/

我正在查看工具提示功能的代码,发现作者正在使用提供程序来公开功能。他是否也可以使用服务或工厂来完成同样的工作?或者是否需要提供者?

这是代码的 link:https://github.com/mgcrea/angular-strap/blob/master/src/tooltip/tooltip.js#L28

谢谢

简答:作者选择了 Provider 作为默认设置 'read-only'。如果他们没有 使用 Provider,代码仍然可以工作,但 Provider 更干净并且 'safer'

ProviderServiceFactory在Angular中都是一样的基本东西,只是API不同而已; Provider 可以 kinda 被认为是 'base' 元素,但它们都有相同的最终目的:创建一个 Angular 可注入。这些可注射物中的每一个都有一个提供蓝图的提供者(Angular 寻找 $get 方法),以及提供者生成的单例实例。如果您使用 FactoryService,Angular 确实在幕后工作,因此您无需了解所有细节;您将只有一个非常无聊的 Provider,它只做基础工作。但是,如果您自己使用 Provider,则可以在声明中为其添加额外的属性和函数。

您可以将 Providers 注入模块的 config() 方法,即 运行 在创建任何单例之前。尝试查看 here 以获得更详细的解释。

在AngularStrap中,作者在Provider上放置了一个'defaults'对象。作者希望您在模块的 config() 方法中修改该对象,然后 Angular 将生成 Singleton。但是,'defaults' 对象在单例不是,因此您不能更改默认值 一旦应用程序是 'running'。即使你在某处再次注入 Provider 并再次更改“默认值”,Angular 也不会重新创建你的单例,因此默认值实际上变成了 'read-only'。这是防止代码进行不需要的更改的好做法,尤其是当您有多个人在同一代码中,或者您知道其他人将使用您的模块时。

您可能会看到其他代码无法像那样工作...也许另一个应用程序只是使用 factory,并将 'defaults' 对象放在该工厂上。它仍然是 'work',并且代码看起来很像当前的样子。然而,因为 'defaults' 将直接在 Singleton 上,你的代码可以在任何时候更改这些设置 如果有人编写代码来这样做。现在您必须留下注释和文档来解释何时更改默认值,何时不更改默认值,等等;对于 99% 的情况,一旦应用 运行ning,默认值永远不需要更改,因此使用 Providermodule.config() 是安全和直接的。

根据官方Angular Documentation

There are five recipe types.

The most verbose, but also the most comprehensive one is a Provider recipe. The remaining four recipe types — Value, Factory, Service and Constant — are just syntactic sugar on top of a provider recipe.

因此,从本质上讲,构建服务和构建提供者是相同的,前提是您不需要访问某些高级设置。他们接着说:

You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts.

这里是 table:

Features / Recipe type

                                 Factory  Service  Value  Constant  Provider
can have dependencies            yes      yes      no     no        yes 
uses type friendly injection     no       yes      yes*   yes*      no 
object available in config phase no       no       no     yes       yes** 
can create functions             yes      yes      yes    yes       yes 
can create primitives            yes      no       yes    yes       yes 

* at the cost of eager initialization by using new operator directly

** the service object is not available during the config phase, but the provider instance is.

虽然文档是正确的,每个都有特殊情况可以使用,但我认为回答它们都是同一件事也很重要。

factoryprovider 的一个特殊版本,在某些情况下,它可以让您使用更少的代码完成同样的事情。反过来 servicevaluefactory 的特例。而 constantvalue.

的特例

这张图片让你一目了然:


(来源:simplygoodcode.com

您可以在图片来自的博客上获得更多详细信息:http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/

关于 Stack Overflow 的另一个问题也有类似的细节:

Angular provides us with three ways to create and register our own service.

工厂

服务

提供商

1. Factory : 当你使用 Factory 时,你创建一个对象,向它添加属性,然后 return 同一个对象。当您将此服务传递到您的控制器时,对象上的这些属性现在将通过您的工厂在该控制器中可用。

示例:

app.controller('myFactoryCtrl', function ($scope, myFactory) {
  $scope.artist = myFactory.getArtist()
});

app.factory('myFactory', function () {
  var _artist = '';
  var service = {}
  service.getArtist = function () {
    return _artist
  }
  return service;
});

2 Service: 当你使用 Service 时,它​​是用‘new’关键字实例化的。因此,您将向“this”添加属性,服务将 return“this”。当您将服务传递到您的控制器时,“this”上的那些属性现在将通过您的服务在该控制器上可用。

示例:

app.controller('myServiceCtrl', function ($scope, myService) {
  $scope.artist = myService.getArtist();
});

app.service('myService', function () {
  var _artist = '';
  this.getArtist = function () {
    return _artist;
  }
});

3 Provider : Providers 是唯一可以传递给 .config() 函数的服务。如果您想在服务对象可用之前为其提供 module-wide 配置,请使用提供程序。

示例:

app.controller('myProviderCtrl', function ($scope, myProvider) {
  $scope.artist = myProvider.getArtist();
  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

app.provider('myProvider', function () {
  this._artist = '';
  this.thingFromConfig = '';

  //Only the properties on the object returned from $get are available in the controller.
  this.$get = function () {
    var that = this;
    return {
      getArtist: function () {
        return that._artist;
      },
      thingonConfig: that.thingFromConfig
    }
  }
});

app.config(function (myProviderProvider) {
  myProviderProvider.thingFromConfig = 'This was set in config()';
});

阅读有关服务的更多信息click here