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


当前回答

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

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

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

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

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

其他回答

了解AngularJS工厂、服务和提供商

所有这些都用于共享可重用的单例对象。它有助于在应用程序/各种组件/模块之间共享可重用代码。

来自文档服务/工厂:延迟实例化–Angular仅在应用程序组件依赖于服务/工厂时实例化它。单件–每个组件依赖于服务获取对单个实例的引用由服务工厂生成。

工厂

工厂是一个函数,您可以在创建对象之前操作/添加逻辑,然后返回新创建的对象。

app.factory('MyFactory', function() {
    var serviceObj = {};
    //creating an object with methods/functions or variables
    serviceObj.myFunction = function() {
        //TO DO:
    };
    //return that object
    return serviceObj;
});

用法

它可以只是像类一样的函数集合。因此,当您将其注入控制器/工厂/指令函数时,它可以在不同的控制器中实例化。每个应用程序只实例化一次。

服务

在查看服务时,只需考虑阵列原型。服务是一个使用“new”关键字实例化新对象的函数。您可以使用this关键字将财产和函数添加到服务对象。与工厂不同,它不返回任何内容(它返回包含方法/财产的对象)。

app.service('MyService', function() {
    //directly binding events to this context
    this.myServiceFunction = function() {
        //TO DO:
    };
});

用法

当您需要在整个应用程序中共享单个对象时,请使用它。例如,经过验证的用户详细信息、可共享的方法/数据、实用程序功能等。

供应商

提供程序用于创建可配置的服务对象。您可以通过config函数配置服务设置。它使用$get()函数返回一个值。$get函数在运行阶段以角度执行。

app.provider('configurableService', function() {
    var name = '';
    //this method can be be available at configuration time inside app.config.
    this.setName = function(newName) {
        name = newName;
    };
    this.$get = function() {
        var getName = function() {
             return name;
        };
        return {
            getName: getName //exposed object to where it gets injected.
        };
    };
});

用法

当您需要在服务对象可用之前为其提供模块化配置时,例如,假设您希望根据环境(如dev、stage或prod)设置API URL

注释只有提供程序在angular的配置阶段可用,而服务和工厂不是。

希望这能澄清您对工厂、服务和供应商的理解。

对我来说,理解差异的最佳和最简单的方法是:

var service, factory;
service = factory = function(injection) {}

AngularJS如何实例化特定组件(简化):

// service
var angularService = new service(injection);

// factory
var angularFactory = factory(injection);

因此,对于服务,AngularJS组件是由服务声明函数表示的类的对象实例。对于工厂,它是从工厂声明函数返回的结果。工厂的行为可能与服务相同:

var factoryAsService = function(injection) {
  return new function(injection) {
    // Service content
  }
}

最简单的思考方式如下:

服务是一个单例对象实例。如果您想为代码提供单例对象,请使用服务。工厂是一个阶级。如果您想为代码提供自定义类,请使用工厂(无法使用服务完成,因为它们已经实例化)。

工厂“类”示例在周围的注释中提供,以及提供程序差异。

JS Fiddle演示

工厂/服务/供应商的“Hello world”示例:

var myApp=角度模块('myApp',[]);//服务风格,可能是最简单的myApp.service('helloWorldFromService',函数(){this.sayHello=函数(){return“你好,世界!”;};});//工厂风格,更加复杂myApp.factory('helloWorldFromFactory',函数(){返回{sayHello:函数(){return“你好,世界!”;}};});//提供程序风格、全面、可配置版本myApp.provider('helloWorld',函数(){this.name='默认值';这一点$get=函数(){var名称=this.name;返回{sayHello:函数(){return“您好,”+name+“!”;}}};this.setName=函数(名称){this.name=名称;};});//嘿,我们可以配置提供者!myApp.config(函数(helloWorldProvider){helloWorldProvider.setName('World');});函数MyCtrl($scope、helloWorld、helloWorldFromFactory、helloWorldFromService){$scope.hellos=[helloWorld.sayHello(),helloWorldFromFactory.sayHello(),helloWorldFromService.sayHello()];}<script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js“></script><body ng app=“myApp”><div ng controller=“MyCtrl”>{{hellos}}</div></body>

已经有好的答案了,但我只想分享这个答案。

首先:Provider是创建服务(单例对象)的方法/方法,该服务假设由$injector注入(AngulaJS如何处理IoC模式)。

以及价值、工厂、服务和常量(4种方式)——相对于提供者方式/接收器的语法糖。

服务与工厂部分已涵盖:https://www.youtube.com/watch?v=BLzNCkPn3ao

服务都是关于新关键字的,实际上我们知道它有四个方面:

创建全新对象将其链接到其原型对象将上下文连接到此并返回此

工厂就是工厂模式的全部内容——包含返回类似服务的对象的函数。

使用其他服务的能力(具有依赖关系)服务初始化延迟/延迟初始化

这个简单/简短的视频:还包括提供商:https://www.youtube.com/watch?v=HvTZbQ_hUZY(在那里你可以看到他们是如何从工厂走向供应商的)

在应用程序完全启动/初始化之前,主要在应用程序配置中使用提供程序配方。

服务与供应商与工厂:

我试图保持简单。这都是关于JavaScript的基本概念。

首先,我们来谈谈AngularJS中的服务!

什么是服务:在AngularJS中,Service只是一个单独的JavaScript对象,可以存储一些有用的方法或财产。此单例对象是根据ngApp(Angular应用程序)创建的,它在当前应用程序中的所有控制器之间共享。当Angularjs实例化服务对象时,它使用唯一的服务名称注册该服务对象。因此,每当我们需要服务实例时,Angular都会在注册表中搜索该服务名称,并返回对服务对象的引用。这样我们就可以调用方法、访问服务对象上的财产等。您可能会有疑问,是否也可以在控制器的范围对象上放置财产和方法!所以为什么需要服务对象?答案是:服务在多个控制器范围内共享。如果您将一些财产/方法放在控制器的范围对象中,它将仅对当前范围可用。但当您在服务对象上定义方法和财产时,它将全局可用,并且可以通过注入该服务在任何控制器的范围内访问。

所以,若有三个控制器作用域,让它是controllerA、controllerB和controllerC,它们都将共享同一个服务实例。

<div ng-controller='controllerA'>
    <!-- controllerA scope -->
</div>
<div ng-controller='controllerB'>
    <!-- controllerB scope -->
</div>
<div ng-controller='controllerC'>
    <!-- controllerC scope -->
</div>

如何创建服务?

AngularJS提供了注册服务的不同方法。在这里,我们将集中讨论工厂(..)、服务(..)和提供者(..)三种方法;

使用此链接进行代码参考

工厂功能:

我们可以如下定义工厂函数。

factory('serviceName',function fnFactory(){ return serviceInstance;})

AngularJS提供了“factory('serviceName',fnFactory)”方法,该方法包含两个参数,serviceName和一个JavaScript函数。Angular通过调用函数fnFactory()创建服务实例,如下所示。

var serviceInstace = fnFactory();

传递的函数可以定义一个对象并返回该对象。AngularJS只是将此对象引用存储到作为第一个参数传递的变量中。从fnFactory返回的任何内容都将绑定到serviceInstance。除了返回对象之外,我们还可以返回函数、值等,无论我们将返回什么,都将可用于服务实例。

例子:

var app= angular.module('myApp', []);
//creating service using factory method
app.factory('factoryPattern',function(){
  var data={
    'firstName':'Tom',
    'lastName':' Cruise',
    greet: function(){
      console.log('hello!' + this.firstName + this.lastName);
    }
  };

  //Now all the properties and methods of data object will be available in our service object
  return data;
});

服务功能:

service('serviceName',function fnServiceConstructor(){})

这是另一种方式,我们可以注册服务。唯一的区别是AngularJS尝试实例化服务对象的方式。这次angular使用“new”关键字并调用如下所示的构造函数。

var serviceInstance = new fnServiceConstructor();

在构造函数中,我们可以使用“this”关键字向服务对象添加财产/方法。例子:

//Creating a service using the service method
var app= angular.module('myApp', []);
app.service('servicePattern',function(){
  this.firstName ='James';
  this.lastName =' Bond';
  this.greet = function(){
    console.log('My Name is '+ this.firstName + this.lastName);
  };
});

提供程序功能:

Provider()函数是创建服务的另一种方法。让我们有兴趣创建一个只向用户显示一些问候信息的服务。但我们也希望提供一个功能,用户可以设置自己的问候语。从技术上讲,我们希望创建可配置的服务。我们如何做到这一点?必须有一种方法,让应用程序可以传递他们的自定义问候消息,Angularjs将其提供给创建我们服务实例的工厂/构造函数。在这种情况下,provider()函数完成任务。使用provider()函数,我们可以创建可配置的服务。

我们可以使用下面给出的提供程序语法创建可配置的服务。

/*step1:define a service */
app.provider('service',function serviceProviderConstructor(){});

/*step2:configure the service */
app.config(function configureService(serviceProvider){});

提供程序语法如何在内部工作?

1.提供程序对象是使用我们在提供程序函数中定义的构造函数创建的。

var serviceProvider = new serviceProviderConstructor();

2.我们在app.config()中传递的函数被执行。这被称为配置阶段,在这里我们有机会定制我们的服务。

configureService(serviceProvider);

3.最后通过调用serviceProvider的$get方法创建服务实例。

serviceInstance = serviceProvider.$get()

使用provide语法创建服务的示例代码:

var app= angular.module('myApp', []);
app.provider('providerPattern',function providerConstructor(){
  //this function works as constructor function for provider
  this.firstName = 'Arnold ';
  this.lastName = ' Schwarzenegger' ;
  this.greetMessage = ' Welcome, This is default Greeting Message' ;
  //adding some method which we can call in app.config() function
  this.setGreetMsg = function(msg){
    if(msg){
      this.greetMessage =  msg ;
    }
  };

  //We can also add a method which can change firstName and lastName
  this.$get = function(){
    var firstName = this.firstName;
    var lastName = this.lastName ;
    var greetMessage = this.greetMessage;
    var data={
       greet: function(){
         console.log('hello, ' + firstName + lastName+'! '+ greetMessage);
       }
    };
    return data ;
  };
});

app.config(
  function(providerPatternProvider){
    providerPatternProvider.setGreetMsg(' How do you do ?');
  }
);

工作演示

摘要:


工厂使用返回服务实例的工厂函数。serviceInstance=fnFactory();

服务使用构造函数,Angular使用“new”关键字调用此构造函数以创建服务实例。serviceInstance=新的fnServiceConstructor();

Provider定义了providerConstructor函数,此providerConstructer函数定义了工厂函数$get。Angular调用$get()来创建服务对象。提供程序语法还有一个额外的优点,即在服务对象实例化之前对其进行配置。serviceInstance=$get();