关于javascript:AngularJS:工厂和服务?

AngularJS : Factory and Service?

本问题已经有最佳答案,请猛点这里访问。

编辑:2016年1月:因为这仍然得到关注。既然问了这个问题,我已经完成了一些AngularJS项目,对于那些我主要使用factory的项目,构建了一个对象,并在最后返回了该对象。然而,我下面的陈述仍然是正确的。

编辑:我想我终于理解了这两者的主要区别,我有一个代码示例要演示。我也认为这个问题与提议的副本不同。副本说服务不可实例化,但是如果您按照下面的演示设置它,它实际上是可实例化的。可以将服务设置为与工厂完全相同。我还将提供代码来显示工厂在哪里服务失败,其他答案似乎都没有。

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

1
2
3
4
5
6
7
var module = angular.module('MyApp.services', []);

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

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

1
2
3
module.controller('StarWarsController', function($scope, VaderService) {
    $scope.luke = VaderService.speak('luke');  
});

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

但是,您可以以与设置工厂完全相同的方式设置服务(即让它返回对象),并且服务的行为与工厂完全相同。

根据这些信息,我看不出有理由使用工厂过度服务,服务可以做工厂能做的一切。

下面是原始问题。

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

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

索引文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
    <head>
    My App
    <script src="lib/angular/angular.js">
    <script type="text/javascript" src="js/controllers.js">
    <script type="text/javascript" src="js/VaderService.js">
    <script type="text/javascript" src="js/app.js">
    </head>

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

App.JS:

1
2
3
4
angular.module('MyApp', [
  'MyApp.services',
  'MyApp.controllers'
]);

控制器:JS:

1
2
3
4
5
6
var module = angular.module('MyApp.controllers', []);

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

VADE Service

1
2
3
4
5
6
7
8
9
10
11
12
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时,我看到了"JointheDarkSideLuke",很好。与预期完全一致。但是,如果我将vaderservice.js更改为此值(注意module.service而不是module.factory):

1
2
3
4
5
6
7
8
9
10
11
12
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完全相同。那么,两者之间真正的功能区别是什么呢??


服务与工厂

enter image description hereenter image description here

工厂和服务之间的区别就像功能和对象之间的区别一样

工厂供应商

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

  • 且只创建一次

  • 可再用元件

  • 工厂是在控制器之间进行通信的一种很好的方式,比如共享数据。

  • 可以使用其他依赖项

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

  • 不能在.config()功能中注入。

  • 用于不可配置的服务

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

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

服务提供商

  • 给我们一个函数(对象)的实例-您刚刚用"new"关键字实例化,然后将属性添加到"this",服务将返回"this"。当您将服务传递到控制器时,"this"上的那些属性现在将通过服务在该控制器上可用。(假设情景)

  • 且只创建一次

  • 可再用元件

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

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

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

  • 用于简单的创建逻辑

  • 不能在.config()功能中注入。

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

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

样例演示

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

AngularJS.服务

1
2
3
4
5
6
7
8
9
10
module.service('MyService', function() {

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

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

安格拉尔工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.factory('MyFactory', function() {

    var factory = {};

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

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

    return factory;
});

还可以看看这些漂亮的东西

对服务和工厂感到困惑

AngularJS工厂、服务和供应商

Angular.js:服务vs供应商vs工厂?


FactoryService只是provider的包装。

工厂

Factory可以返回任何可以是class(constructor function)instance of classstringnumberboolean的东西。如果返回constructor函数,则可以在控制器中实例化。

1
2
3
4
5
6
7
8
9
 myApp.factory('myFactory', function () {

  // any logic here..

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

服务

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

1
2
3
4
5
6
myApp.service('myService', function () {

  // any logic here..

  this.name = 'Joe';
}

服务背后的实际AngularJS代码

1
2
3
4
5
function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
        return $injector.instantiate(constructor);
    }]);
}

它只是一个包装在Factory上。如果您从Service返回一些内容,那么它的行为将类似于Factory

IMPORTANT:工厂和服务返回结果为缓存,所有控制器返回相同结果。

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

在所有情况下,Factory都是最好的。它可以在您具有需要在不同控制器中实例化的constructor功能时使用。

ServiceSingleton对象的一种。对于所有控制器,从服务返回的对象将是相同的。当您希望整个应用程序具有单个对象时,可以使用它。经过身份验证的用户详细信息。

为了进一步理解,请阅读

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

AngularJS Service / Factory Tutorial with Example


  • 如果使用服务,您将获得函数的实例("this"关键字)。
  • 如果您使用工厂,您将获得通过调用函数引用(返回语句工厂)

工厂和服务是最常用的配方。它们之间的唯一区别是,服务配方对自定义类型的对象更有效,而工厂可以生成JavaScript原语和函数。

参考文献


$提供服务

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

  • 如果您使用的是类:您可以使用服务符号。
  • 如果您使用的是一个对象:您可以使用工厂符号。

ServiceFactory符号之间的唯一区别是服务是新的ed,而工厂不是。但对于其他的一切,它们看起来、闻起来和行为都是一样的。同样,它只是$provide.provider函数的简写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 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);