AngularJS:工厂和服务? [复制]

Posted

技术标签:

【中文标题】AngularJS:工厂和服务? [复制]【英文标题】:AngularJS : Factory and Service? [duplicate] 【发布时间】:2014-05-29 06:51:10 【问题描述】:

2016 年 1 月编辑:因为这仍然引起了关注。自从提出这个问题以来,我已经完成了一些 AngularJS 项目,对于那些我主要使用 factory 的项目,构建了一个对象并在最后返回了该对象。但是,我的以下陈述仍然正确。

编辑:我想我终于明白了两者之间的主要区别,并且我有一个代码示例来演示。我也认为这个问题与建议的副本不同。副本说服务是不可实例化的,但如果你按照我在下面演示的那样设置它,它实际上是。可以将服务设置为与工厂完全相同。我还将提供代码来显示工厂故障转移服务的位置,这似乎没有其他答案。

如果我这样设置 VaderService(即作为服务):

var module = angular.module('MyApp.services', []);

module.service('VaderService', function() 
    this.speak = function (name) 
        return 'Join the dark side ' + name;
    
);

然后在我的控制器中我可以这样做:

module.controller('StarWarsController', function($scope, VaderService) 
    $scope.luke = VaderService.speak('luke');   
);

通过服务,注入控制器的 VaderService 被实例化,所以我可以调用 VaderService.speak,但是,如果我将 VaderService 更改为 module.factory,控制器中的代码将不再工作,这是主要的区别。使用工厂,注入控制器的 VaderService 没有实例化,这就是为什么在设置工厂时需要返回一个对象(请参阅问题中的示例)。

但是,您可以像设置工厂一样设置服务(IE 让它返回一个对象)并且服务的行为与工厂完全相同

鉴于这些信息,我认为没有理由使用工厂而不是服务,服务可以做工厂可以做的一切,甚至更多。

下面的原始问题。


我知道这已经被问过很多次了,但我真的看不出工厂和服务之间的任何功能差异。我读过这个教程:http://blogs.clevertech.biz/startupblog/angularjs-factory-service-provider

它似乎给出了一个相当好的解释,但是,我将我的应用程序设置如下:

index.html

<!DOCTYPE html>
<html>
    <head>
    <title>My App</title>
    <script src="lib/angular/angular.js"></script>
    <script type="text/javascript" src="js/controllers.js"></script>
    <script type="text/javascript" src="js/VaderService.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
    </head>

    <body ng-app="MyApp"> 
        <table ng-controller="StarWarsController">
            <tbody>
            <tr><td>luke</td></tr>
            </tbody>
        </table>
    </body>
</html>

app.js:

angular.module('MyApp', [
  'MyApp.services',
  'MyApp.controllers'
]);

controllers.js:

var module = angular.module('MyApp.controllers', []);

module.controller('StarWarsController', function($scope, VaderService) 
    var luke = new VaderService('luke');
    $scope.luke = luke.speak();
);

VaderService.js

var module = angular.module('MyApp.services', []);

module.factory('VaderService', function() 
    var VaderClass = function(padawan) 
        this.name = padawan;
        this.speak = function () 
            return 'Join the dark side ' + this.name;
        
    

    return VaderClass;
);

然后,当我加载 index.html 时,我看到“加入黑暗面卢克”,太好了。完全符合预期。但是,如果我将 VaderService.js 更改为此(注意 module.service 而不是 module.factory):

var module = angular.module('MyApp.services', []);

module.service('VaderService', function() 
    var VaderClass = function(padawan) 
        this.name = padawan;
        this.speak = function () 
            return 'Join the dark side ' + this.name;
        
    

    return VaderClass;
);

然后重新加载 index.html(我确保清空了缓存并进行了硬重新加载)。它的工作原理完全与使用 module.factory 时相同。那么两者之间真正的功能区别是什么?

【问题讨论】:

Here are some good answers 关于 servicesfactoriesproviders 的工作原理。 您编辑的部分比这里的任何其他答案都更有意义:) 【参考方案1】:

服务 vs 工厂


工厂和服务的区别就像函数和对象的区别

工厂供应商

给我们函数的返回值,即。您只需创建一个对象,为其添加属性,然后返回相同的对象。当您将此服务传递到您的控制器时,对象上的这些属性现在将通过您的工厂在该控制器中可用。 (假设情景)

单例且只会创建一次

可重用组件

工厂是在控制器之间进行通信(如共享数据)的绝佳方式。

可以使用其他依赖项

通常在服务实例需要复杂的创建逻辑时使用

无法注入.config() 函数。

用于不可配置的服务

如果您使用的是对象,则可以使用工厂提供程序。

语法:module.factory('factoryName', function);

服务提供商

给我们一个函数(对象)的实例——你刚刚用'new'关键字实例化,你将向'this'添加属性,服务将返回'this'。当你传递服务时进入您的控制器,“this”上的这些属性现在将通过您的服务在该控制器上可用。 (假设情景)

单例且只会创建一次

可重用组件

服务用于控制器之间的通信以共享数据

您可以使用this 关键字向服务对象添加属性和函数

依赖项作为构造函数参数注入

用于简单的创建逻辑

无法注入.config() 函数。

如果您使用的是类,则可以使用服务提供者

语法:module.service(‘serviceName’, function);

Sample Demo

在下面的示例中,我定义了MyServiceMyFactory。请注意在.service 中我如何使用this.methodname. 创建服务方法在.factory 中我创建了一个工厂对象并将方法分配给它。

AngularJS .service


module.service('MyService', function() 

    this.method1 = function() 
            //..method1 logic
        

    this.method2 = function() 
            //..method2 logic
        
);

AngularJS .factory


module.factory('MyFactory', function() 

    var factory = ; 

    factory.method1 = function() 
            //..method1 logic
        

    factory.method2 = function() 
            //..method2 logic
        

    return factory;
);

也看看这些漂亮的东西

Confused about service vs factory

AngularJS Factory, Service and Provider

Angular.js: service vs provider vs factory?

【讨论】:

这对我来说很有意义!所以我可以想象让服务表现得像一个工厂,但这与服务的设计用途背道而驰。此外,如果我在使用 module.factory 时不返回任何内容,事情将无法正常工作,对吗? 是我自己还是服务好像有点没意义? 最后一个链接失效了。 我不喜欢工厂示例,因为它与服务相同(虽然有效)。工厂可以返回函数,但两者在概念上的区别应该是关于变量——服务就像类(New = 空对象)和工厂像对象(= 静态数据/值)。 因此,作为使用“服务”在两个控制器之间进行通信以更新影响两个单独控制器的单个变量的人,服务是正确的方式吗?【参考方案2】:

FactoryService 只是 provider 的包装器。

工厂

Factory 可以返回任何可以是 class(constructor function)instance of classstringnumberboolean 的内容。如果你返回一个constructor 函数,你可以在你的控制器中实例化。

 myApp.factory('myFactory', function () 

  // any logic here..

  // Return any thing. Here it is object
  return 
    name: 'Joe'
  

服务

服务不需要返回任何东西。但是您必须在 this 变量中分配所有内容。因为服务将默认创建实例并将其用作基础对象。

myApp.service('myService', function () 

  // any logic here..

  this.name = 'Joe';

服务背后的实际 angularjs 代码

function service(name, constructor) 
    return factory(name, ['$injector', function($injector) 
        return $injector.instantiate(constructor);
    ]);

它只是factory 的包装。如果你从service 返回一些东西,那么它的行为就像Factory

IMPORTANT:Factory 和 Service 的返回结果会被缓存,所有控制器都返回相同的结果。

我应该什么时候使用它们?

Factory 在所有情况下都是最可取的。当你有constructor函数需要在不同的控制器中实例化时可以使用它。

Service 是一种Singleton 对象。从服务返回的对象对于所有控制器都是相同的。当您想为整个应用程序拥有单个对象时,可以使用它。 例如:经过身份验证的用户详细信息。

为了进一步了解,请阅读

http://iffycan.blogspot.in/2013/05/angular-service-or-factory.html

http://viralpatel.net/blogs/angularjs-service-factory-tutorial/

【讨论】:

那你为什么要选择一个而不是另一个呢?你能给我一个可靠的例子,说明工厂可以做而服务不能做的事情吗?我还是不太明白其中的区别。 更新了您何时需要使用它们的答案。 由于工厂允许您返回对象,因此您可以控制公开的内容,这意味着您可以在工厂中拥有私有方法。使用服务,整个对象都暴露出来了。 @eet,在服务中我们也可以有私有方法。您分配给this 对象的任何内容都将被公开。其他功能是私有的。服务只是减少自己创建对象。 服务和工厂都是单例的。【参考方案3】:

$提供服务

它们在技术上是相同的,实际上是使用$provide service 的provider 函数的不同表示法。

如果您使用的是类:您可以使用 service 表示法。 如果您使用的是对象:您可以使用 factory 表示法。

servicefactory 之间唯一的区别表示法是服务是new-ed而工厂是不是。但对于其他一切,它们外观气味行为都相同。同样,它只是 $provide.provider 函数的简写。

// Factory

angular.module('myApp').factory('myFactory', function() 

  var _myPrivateValue = 123;

  return 
    privateValue: function()  return _myPrivateValue; 
  ;

);

// Service

function MyService() 
  this._myPrivateValue = 123;


MyService.prototype.privateValue = function() 
  return this._myPrivateValue;
;

angular.module('myApp').service('MyService', MyService);

【讨论】:

【参考方案4】: 如果您使用服务,您将获得一个函数的实例(“this” 关键词)。 如果您使用工厂,您将获得以下值 通过调用函数引用返回(中的 return 语句 工厂)

Factory 和 Service 是最常用的配方。它们之间的唯一区别是 Service recipe 更适用于自定义类型的对象,而 Factory 可以生成 JavaScript 原语和函数。

Reference

【讨论】:

我不太明白这意味着什么。你能给我举个例子,说明你可以用工厂做些什么,但不能用服务做,反之亦然?

以上是关于AngularJS:工厂和服务? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我应该在 AngularJS 中选择使用服务而不是工厂? [复制]

javascript AngularJS中服务,工厂和提供商之间的区别

AngularJS:何时使用服务而不是工厂

AngularJS:何时使用服务而不是工厂

AngularJS:为啥在说“服务”时使用“工厂”?

angular js:是不是需要在模块文件中加载所有控制器和工厂/服务