请耐心听我说。我知道还有其他答案,比如:
AngularJS:服务vs提供商vs工厂
然而,我仍然不知道你什么时候会使用服务而不是工厂。
据我所知,factory通常用于创建可以被多个控制器调用的“通用”函数:创建通用控制器函数
比起服务,Angular文档似乎更喜欢工厂。他们甚至在使用工厂时提到“服务”,这更令人困惑!http://docs.angularjs.org/guide/dev_guide.services.creating_services
那么什么时候使用服务呢?
是否有一些事情只有通过服务才能做到或更容易做到?
幕后有什么不同吗?性能/内存差异呢?
举个例子。除了声明的方法,它们看起来是一样的,我不明白为什么我要做一个而不是另一个。http://jsfiddle.net/uEpkE/
更新:从Thomas的回答中,似乎暗示服务是为了更简单的逻辑,而工厂是为了更复杂的逻辑和私有方法,所以我更新了下面的小提琴代码,似乎两者都能支持私有函数?
myApp.factory('fooFactory', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo; }
return {
setFoobar: function(foo){
addHi(foo);
},
getFoobar:function(){
return fooVar;
}
};
});
myApp.service('fooService', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo;}
this.setFoobar = function(foo){
addHi(foo);
}
this.getFoobar = function(){
return fooVar;
}
});
function MyCtrl($scope, fooService, fooFactory) {
fooFactory.setFoobar("fooFactory");
fooService.setFoobar("fooService");
//foobars = "Hi fooFactory, Hi fooService"
$scope.foobars = [
fooFactory.getFoobar(),
fooService.getFoobar()
];
}
Allernhwkim最初发布了这个问题的答案,链接到他的博客上,但被版主删除了。这是我发现的唯一一篇文章,它不仅告诉你如何用服务、提供者和工厂做同样的事情,而且还告诉你用提供者可以做什么而用工厂不能做什么,用工厂不能做什么。
直接来自他的博客:
app.service('CarService', function() {
this.dealer="Bad";
this.numCylinder = 4;
});
app.factory('CarFactory', function() {
return function(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
};
});
app.provider('CarProvider', function() {
this.dealerName = 'Bad';
this.$get = function() {
return function(numCylinder) {
this.numCylinder = numCylinder;
this.dealer = this.dealerName;
}
};
this.setDealerName = function(str) {
this.dealerName = str;
}
});
这表明CarService总是生产4汽缸的汽车,你不能为单个汽车更改它。而CarFactory返回一个函数,所以你可以在你的控制器中做新的CarFactory,传递一些特定于那辆车的圆柱体。你不能创建新的CarService因为CarService是一个对象而不是一个函数。
工厂不这样运作的原因是:
app.factory('CarFactory', function(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
});
并自动返回一个函数让你实例化,是因为你不能这样做(添加东西到原型/等):
app.factory('CarFactory', function() {
function Car(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
};
Car.prototype.breakCylinder = function() {
this.numCylinder -= 1;
};
return Car;
});
看看它是如何字面上生产汽车的工厂。
他博客的结论很好:
In conclusion,
---------------------------------------------------
| Provider| Singleton| Instantiable | Configurable|
---------------------------------------------------
| Factory | Yes | Yes | No |
---------------------------------------------------
| Service | Yes | No | No |
---------------------------------------------------
| Provider| Yes | Yes | Yes |
---------------------------------------------------
Use Service when you need just a simple object such as a Hash, for
example {foo;1, bar:2} It’s easy to code, but you cannot instantiate
it.
Use Factory when you need to instantiate an object, i.e new
Customer(), new Comment(), etc.
Use Provider when you need to configure it. i.e. test url, QA url,
production url.
如果你发现你只是在工厂中返回一个对象,你可能应该使用service。
不要这样做:
app.factory('CarFactory', function() {
return {
numCylinder: 4
};
});
改用service:
app.service('CarService', function() {
this.numCylinder = 4;
});
服务
语法:模块。service('serviceName',函数);
结果:当将serviceName声明为可注入参数时,你将得到传递给module.service的实际函数引用。
使用方法:可以通过简单地将()附加到注入的函数引用来共享有用的实用程序函数。也可以用injectedArg运行。调用(这个)或类似的方法。
工厂
语法:模块。factory('factoryName',函数);
结果:当将factoryName声明为一个可注入参数时,你将得到通过调用传递给module.factory的函数引用返回的值。
用法:可能用于返回一个'class'函数,然后可以重新创建实例。
供应商
语法:模块。provider('providerName',函数);
结果:当将providerName声明为一个可注入参数时,您将获得通过调用传递给module.provider的函数引用的$get方法返回的值。
用途:可能用于返回一个'类'函数,然后可以重新创建实例,但在注入之前需要某种配置。也许对跨项目可重用的类有用?我还是不太清楚。
解释
这里有不同的东西:
第一:
如果你使用一个服务,你将得到一个函数的实例("this")
关键字)。
如果您使用工厂,您将获得返回的值
调用函数引用(工厂中的return语句)。
裁判:角。Service vs angular.factory
第二:
记住,AngularJS中的所有提供者(value, constant, services, factories)都是单例的!
第三:
使用一种或另一种(服务或工厂)取决于代码风格。
但是,AngularJS中常用的方法是使用工厂。
为什么?
因为“工厂方法是将对象导入AngularJS依赖注入系统的最常用方法。它非常灵活,可以包含复杂的创建逻辑。由于工厂是常规函数,我们还可以利用新的词法作用域来模拟“私有”变量。这非常有用,因为我们可以隐藏给定服务的实现细节。”
(参考:http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821)。
使用
Service:可以通过将()附加到注入的函数引用来共享有用的实用程序函数。也可以使用injectedArg.call(this)或类似的方法运行。
Factory:可能用于返回一个' class '函数,然后可以重新创建实例。
因此,当您的服务中有复杂的逻辑而又不想暴露这种复杂性时,请使用工厂。
在其他情况下,如果你想返回一个服务的实例,只需使用service。
但是随着时间的推移你会发现80%的情况下你会用到工厂。
详情请访问:http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/
更新:
这里有很棒的帖子:
http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html
如果你想让你的函数像普通函数一样被调用,请使用
工厂。如果你想要你的函数用new
接线员,使用服务。如果你不知道其中的区别,就用factory。”
更新:
AngularJS团队做了他的工作并给出了解释:
http://docs.angularjs.org/guide/providers
从这一页开始:
“工厂和服务是最常用的食谱。它们之间唯一的区别是Service recipe更好地用于自定义类型的对象,而Factory可以生成JavaScript原语和函数。”