AngularJS中的服务、提供商和工厂之间有什么区别?


当前回答

句法糖是区别。只需要提供程序。或者换句话说,只有提供者才是真正的角度,所有其他提供者都是派生的(以减少代码)。还有一个简单的版本,叫做Value(),它只返回值,不返回计算或函数。偶数值是从提供程序派生的!

那么,为什么会出现这样的并发症,为什么我们不能只使用提供者而忘记其他一切呢?它应该可以帮助我们轻松编写代码,更好地进行沟通。开玩笑的回答是,它越复杂,框架的销售就越好。


可以返回value=value的提供程序一个可以实例化并返回=工厂(+值)提供程序可以实例化+做某事=服务(+工厂,+值)提供者=必须包含名为$get(+Factory,+Service,+Value)的属性

角注入为我们得出这一结论提供了第一个线索。

$injector用于检索提供者“不是服务,不是工厂,而是提供者”定义的对象实例。

更好的答案是:Angular服务由服务工厂创建。这些服务工厂是由服务提供程序创建的函数。服务提供程序是构造函数。实例化时,它们必须包含名为$get的属性,该属性保存服务工厂函数

因此,主供应器和注入器都将就位:)。当$get可以通过从IServiceProvider继承而在提供程序中实现时,Typescript就变得有趣了。

其他回答

对于新手来说,这是一个非常令人困惑的部分,我试图用简单的语言来解释它

AngularJS服务:用于与控制器中的服务引用共享实用程序函数。服务本质上是单例的,因此对于一个服务,浏览器中只创建一个实例,并且在整个页面中使用相同的引用。

在服务中,我们使用此对象创建函数名作为属性。

AngularJS Factory:Factory的用途也与Service相同,但在本例中,我们创建了一个新对象,并添加函数作为该对象的财产,最后返回该对象。

AngularJS Provider:其目的也是相同的,不过Provider提供了$get函数的输出。

定义和使用服务、工厂和提供商在http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider

所有的好答案都已经有了。我想在服务和工厂方面再补充几点。以及服务/工厂之间的差异。你也可以有这样的问题:

我应该使用服务还是工厂?有什么不同?他们的行为是否相同?

让我们从服务和工厂之间的区别开始:

两者都是Singleton:每当Angular第一次发现它们作为依赖项时,它都会创建服务/工厂的单个实例。创建实例后,将永远使用同一实例。可用于对具有行为的对象进行建模:它们都可以有方法、内部状态变量等。尽管编写代码的方式会有所不同。

服务:

服务是一个构造函数,Angular将通过调用newyourServiceName()来实例化它。这意味着一些事情。

函数和实例变量将是它的财产。您不需要返回值。当Angular调用new yourServiceName()时,它将接收此对象以及您在其上放置的所有财产。

示例:

angular.service('MyService', function() {
  this.aServiceVariable = "Ved Prakash"
  this.aServiceMethod = function() {
    return //code
  };
});

当Angular将此MyService服务注入控制器时取决于它,该控制器将获得它可以调用的MyService上的函数,例如MyService.aServiceMethod()。

注意:

由于构造的服务是一个对象,因此当调用它们时,它内部的方法可以引用它:

angular.service('ScoreKeeper', function($http) {
  this.score = 0;

  this.getScore = function() {
    return this.score;
  };

  this.setScore = function(newScore) {
    this.score = newScore;
  };

  this.addOne = function() {
    this.score++;
  };
});

例如,如果您通过从服务器$http.get('/score').then(ScoreKeeper.setScore)获取分数来初始化分数,那么您可能会尝试在承诺链中调用ScoreKeeper。这样做的问题是,ScoreKeeer.setScore将在该绑定为空的情况下被调用,并且您会收到错误。更好的方法是$http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper))。无论您是否选择在服务方法中使用它,请注意如何调用它们。

从服务返回值:

由于JavaScript构造函数的工作方式,若从构造函数函数返回一个复杂值(即Object),调用者将获得该Object而不是该实例。

这意味着你基本上可以从下面复制粘贴工厂示例,用服务替换工厂,它会起作用:

angular.service('MyService', function($http) {
  var api = {};

  api.aServiceMethod= function() {
    return $http.get('/users');
  };
  return api;
});

因此,当Angular使用新的MyService()构造服务时,它将获得该api对象而不是MyService实例。

这是任何复杂值(对象、函数)的行为,但不是基本类型的行为。

工厂:

工厂是一个返回值的普通旧函数。返回值是注入到依赖于工厂的事物中的值。Angular中的一个典型工厂模式是返回一个具有函数作为财产的对象,如下所示:

angular.factory('MyFactory', function($http) {
  var api = {};

  api.aFactoryMethod= function() {
    return $http.get('/users');
  };

  return api;
});

工厂依赖项的注入值是工厂的返回值值,并且它不必是对象。这可能是一种功能

以上1和2个问题的答案:

大多数情况下,只要坚持使用工厂就可以了。他们的行为更容易理解。别无选择关于是否返回一个值,此外,没有错误如果你做错事,就会被介绍。当我谈论注射时,我仍然将其称为“服务”但它们是依赖关系。服务/工厂行为非常相似,有些人会说任何一个都很好。这有点正确,但我觉得遵循约翰·帕帕风格指南的建议,坚持工厂**

所有服务均为单人服务;每个应用程序实例化一次。它们可以是任何类型,无论是原语、对象文本、函数,甚至是自定义类型的实例。

值、工厂、服务、常量和提供程序方法都是提供程序。他们教Injector如何实例化服务。

最冗长,但也是最全面的是提供者配方其余四种配方类型-价值、工厂、服务和常量-只是提供程序配方之上的语法糖。

Value Recipe是最简单的例子,您自己实例化服务,并将实例化的值提供给注入器。Factory配方为Injector提供了一个工厂函数,当它需要实例化服务时调用该函数。调用时,工厂函数创建并返回服务实例。服务的依赖项作为函数的参数注入。因此,使用此配方可增加以下功能:能够使用其他服务(具有依赖关系)服务初始化延迟/延迟初始化Service配方与Factory配方几乎相同,但这里Injector调用带有新运算符的构造函数,而不是工厂函数。提供商的配方通常是过度的。它通过允许您配置工厂的创建,增加了一个间接层。

只有当您想要公开API时,才应该使用Provider配方对于必须在应用程序启动。这通常只对可重复使用有用其行为可能需要在应用。常量配方与值配方类似,只是它允许您定义在配置阶段可用的服务。比使用Value配方创建的服务更快。与Values不同,它们不能使用decorator进行装饰。请参阅提供程序文档。

工厂:您实际在工厂内部创建对象并将其返回的工厂。service:您只有一个使用this关键字定义函数的标准函数的服务。provider:您定义了一个$get,它可以用来获取返回数据的对象。

1.服务是在必要时创建的单例对象,在应用程序生命周期结束之前(浏览器关闭时)不会被清理。控制器在不再需要时被销毁和清理。

2.创建服务的最简单方法是使用factory()方法。factory()方法允许我们通过返回包含服务函数和服务数据的对象来定义服务。服务定义函数是我们放置可注入服务的地方,例如$http和$q。前任:

angular.module('myApp.services')
.factory('User', function($http) { // injectables go here
var backendUrl = "http://localhost:3000"; var service = {
    // our factory definition
user: {},
setName: function(newName) {
      service.user['name'] = newName;
    },
setEmail: function(newEmail) { service.user['email'] = newEmail;
},
save: function() {
return $http.post(backendUrl + '/users', { user: service.user
}); }
};
return service; });

在我们的应用程序中使用factory()

在我们的应用程序中使用工厂很容易,因为我们可以在运行时在需要的地方简单地注入工厂。

angular.module('myApp')
.controller('MainController', function($scope, User) {
  $scope.saveUser = User.save;
});

另一方面,service()方法允许我们通过定义构造函数来创建服务。我们可以使用原型对象来定义服务,而不是原始javascript对象。与factory()方法类似,我们还将在函数定义中设置可注入项。创建服务的最低级方法是使用provide()方法。这是创建可以使用.config()函数配置的服务的唯一方法。与前面的to方法不同,我们将在定义的this中设置可注射对象$get()函数定义。