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

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

演示的示例代码:

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()适合那些以更面向对象的风格(c# /Java)编写代码的人(使用这个关键字并通过prototype/Constructor函数实例化对象)。

Factory是为那些编写更自然的javascript/函数式代码的开发人员准备的。

看看angular.js中.service和.factory方法的源代码——在内部它们都调用provider方法:

  function provider(name, provider_) {
    if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw Error('Provider ' + name + ' must define $get factory method.');
    }
    return providerCache[name + providerSuffix] = provider_;
  }

  function factory(name, factoryFn) { \
    return provider(name, { $get: factoryFn }); 
  }

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

其他回答

补充第一个答案,我认为.service()适合那些以更面向对象的风格(c# /Java)编写代码的人(使用这个关键字并通过prototype/Constructor函数实例化对象)。

Factory是为那些编写更自然的javascript/函数式代码的开发人员准备的。

看看angular.js中.service和.factory方法的源代码——在内部它们都调用provider方法:

  function provider(name, provider_) {
    if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw Error('Provider ' + name + ' must define $get factory method.');
    }
    return providerCache[name + providerSuffix] = provider_;
  }

  function factory(name, factoryFn) { \
    return provider(name, { $get: factoryFn }); 
  }

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

这里有更多的服务与工厂的例子,这些例子可能有助于了解它们之间的区别。基本上,一个服务调用了“new…”,它已经被实例化了。工厂不会自动实例化。

基本的例子

返回一个只有一个方法的类对象

下面是一个只有一个方法的服务:

angular.service('Hello', function () {
  this.sayHello = function () { /* ... */ };
});

下面是一个工厂,它返回一个带有方法的对象:

angular.factory('ClassFactory', function () {
  return {
    sayHello: function () { /* ... */ }
  };
});

返回一个值

返回数字列表的工厂:

angular.factory('NumberListFactory', function () {
  return [1, 2, 3, 4, 5];
});

console.log(NumberListFactory);

一个返回数字列表的服务:

angular.service('NumberLister', function () {
  this.numbers = [1, 2, 3, 4, 5];
});

console.log(NumberLister.numbers);

这两种情况下的输出是相同的,都是数字列表。

先进的例子

使用工厂“分类”变量

在这个例子中,我们定义了一个CounterFactory,它增加或减少一个计数器,你可以得到当前的计数或已经创建了多少个CounterFactory对象:

angular.factory('CounterFactory', function () {
  var number_of_counter_factories = 0; // class variable

  return function () {
    var count = 0; // instance variable
    number_of_counter_factories += 1; // increment the class variable

    // this method accesses the class variable
    this.getNumberOfCounterFactories = function () {
      return number_of_counter_factories;
    };

    this.inc = function () {
      count += 1;
    };
    this.dec = function () {
      count -= 1;
    };
    this.getCount = function () {
      return count;
    };
  }

})

我们使用CounterFactory创建多个计数器。我们可以访问class变量来查看创建了多少个计数器:

var people_counter;
var places_counter;

people_counter = new CounterFactory();
console.log('people', people_counter.getCount());
people_counter.inc();
console.log('people', people_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());

places_counter = new CounterFactory();
console.log('places', places_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());
console.log('counters', places_counter.getNumberOfCounterFactories());

这段代码的输出是:

people 0
people 1
counters 1
places 0
counters 2
counters 2

所有提供者都以相同的方式工作。不同的方法服务、工厂、提供者只是让你用更少的代码完成同样的事情。

附注:还有价值和常数。

从提供者开始到价值结束的链条上的每个特殊情况都有一个附加的限制。所以要在两者之间做出选择,你必须问问自己,哪一个能让你用更少的代码完成你想要的。

下面这张图可以说明我的意思:

你可以在我的博客文章中找到这张照片的分类和参考指南:

http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/

还有一种方法可以返回构造函数,这样你就可以在工厂中返回可更新的类,像这样:

function MyObjectWithParam($rootScope, name) {
  this.$rootScope = $rootScope;
  this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
  return this.name;
};

App.factory('MyObjectWithParam', function ($injector) {
  return function(name) { 
    return $injector.instantiate(MyObjectWithParam,{ name: name });
  };
}); 

你可以在控制器中做这个,它使用MyObjectWithParam:

var obj = new MyObjectWithParam("hello"),

完整的例子如下: http://plnkr.co/edit/GKnhIN?p=preview

这里是谷歌小组页面,讨论的地方: https://groups.google.com/forum/ !味精/角度/ 56 sdorweoqg / b8hdPskxZXsJ

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