根据我的理解,当我在工厂中返回一个被注入到控制器的对象。当在服务中,我使用这个处理对象,不返回任何东西。

我假设服务总是单例的,并且每个控制器中都会注入一个新的工厂对象。然而,正如事实证明的那样,工厂对象也是单例的吗?

演示的示例代码:

var factories = angular.module('app.factories', []);
var app = angular.module('app',  ['ngResource', 'app.factories']);

factories.factory('User', function () {
  return {
    first: 'John',
    last: 'Doe'
  };
});

app.controller('ACtrl', function($scope, User) {
  $scope.user = User;
});

app.controller('BCtrl', function($scope, User) {
  $scope.user = User;
});

更改用户时。首先在ACtrl中,结果是那个用户。BCtrl中的first也改变了,例如User is a singleton?

我的假设是一个新的实例被注入到一个带有工厂的控制器中?


当前回答

非常简单:

.service——注册的函数将作为构造函数被调用(又名'newed')

.factory注册的函数将被作为一个简单函数调用

两者都被调用一次,导致一个单例对象被注入到应用程序的其他组件中。

其他回答

这将是理解服务Vs工厂Vs提供商的最佳和简短的答案

来源:https://groups.google.com/forum/ !味精/角度/ 56 sdorweoqg / HuZsOsMvKv4J

这里本说的演示http://jsbin.com/ohamub/1/edit?html,output

“代码中有一些注释说明了主要的差异,但我将在这里展开一点。作为说明,我只是在思考这个问题,所以如果我说错了什么,请告诉我。

服务

语法:模块。service('serviceName',函数);

结果:当将serviceName声明为可注入参数时,你将得到传递给module.service的实际函数引用。

使用方法:可以通过简单地将()附加到注入的函数引用来共享有用的实用程序函数。也可以用injectedArg运行。调用(这个)或类似的方法。

工厂

语法:模块。factory('factoryName',函数);

结果:当将factoryName声明为一个可注入参数时,你将得到通过调用传递给module.factory的函数引用返回的值。

用法:可能用于返回一个'class'函数,然后可以重新创建实例。

供应商

语法:模块。provider('providerName',函数);

结果:当将providerName声明为一个可注入参数时,您将获得通过调用传递给module.provider的函数引用的$get方法返回的值。

用途:可能用于返回一个'类'函数,然后可以重新创建实例,但在注入之前需要某种配置。也许对跨项目可重用的类有用?这一点还不太清楚。” 本

基本的区别在于,提供程序允许将原语(非对象)、数组或回调函数的值设置到工厂声明的变量中,因此如果返回一个对象,它必须显式地声明和返回。

另一方面,服务只能用于将服务声明的变量设置为对象,因此可以避免显式地创建和返回对象,而另一方面,它允许使用this关键字。

或者简而言之,“提供者是一种更通用的形式,而服务仅限于对象”。

生活的例子

" Hello world "的例子

与工厂/服务/供应商:

var myApp = angular.module('myApp', []);
 
//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});
 
//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});
    
//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {
    // In the provider function, you cannot inject any
    // service or factory. This can only be done at the
    // "$get" method.
 
    this.name = 'Default';
 
    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };
 
    this.setName = function(name) {
        this.name = name;
    };
});
 
//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});
        
 
function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
    
    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}​

在AngularJS中有三种处理业务逻辑的方法:(灵感来自Yaakov的Coursera AngularJS课程):

服务 工厂 提供者

这里我们只讨论服务vs工厂

服务:

语法:

app.js

 var app = angular.module('ServiceExample',[]);
 var serviceExampleController =
              app.controller('ServiceExampleController', ServiceExampleController);
 var serviceExample = app.service('NameOfTheService', NameOfTheService);

 ServiceExampleController.$inject = ['NameOfTheService'] //very important as this protects from minification of js files

function ServiceExampleController(NameOfTheService){
     serviceExampleController = this;
     serviceExampleController.data = NameOfTheService.getSomeData();
 }

function NameOfTheService(){
     nameOfTheService = this;
     nameOfTheService.data = "Some Data";
     nameOfTheService.getSomeData = function(){
           return nameOfTheService.data;
     }     
}

index . html

<div ng-controller = "ServiceExampleController as serviceExample">
   {{serviceExample.data}}
</div>

服务的主要特点:

惰性实例化:如果服务没有被注入,它将永远不会被实例化。所以要使用它,你必须将它注入到一个模块中。 单例:如果它被注入到多个模块中,所有模块都只能访问一个特定的实例。这就是为什么在不同的控制器之间共享数据是非常方便的。

工厂

现在让我们来谈谈AngularJS中的工厂

首先让我们看一下语法:

app.js:

var app = angular.module('FactoryExample',[]);
var factoryController = app.controller('FactoryController', FactoryController);
var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);

//first implementation where it returns a function
function NameOfTheFactoryOne(){
   var factory = function(){
      return new SomeService();
    }
   return factory;
}

//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
   var factory = {
      getSomeService : function(){
          return new SomeService();
       }
    };
   return factory;
}

现在在控制器中使用上述两个:

 var factoryOne = NameOfTheFactoryOne() //since it returns a function
 factoryOne.someMethod();

 var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
 factoryTwo.someMethod();

工厂特点:

这种类型的服务遵循工厂设计模式。工厂可以被认为是创建新对象或方法的中心场所。 这不仅可以生成单例服务,还可以生成可定制的服务。 .service()方法是一个工厂,它总是生成相同类型的服务,即单例服务。没有简单的方法来配置它的行为。.service()方法通常用作不需要任何配置的快捷方式。

You can understand the difference with this analogy - Consider the difference between a normal function that will return some value and constructor function that will get instantiated using new keyword.So creating factory is just similar to create normal function that will return some value(primitive or an object) whereas creating service is like creating constructor function(OO class) of which we can create instance using new keyword. The only thing to notice is here is that when we use Service method to create services it will automatically create instance of it using dependency injection mechanism supported by AngularJS