请耐心听我说。我知道还有其他答案,比如:
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()
];
}
与服务相比,没有什么是工厂做不到或做得更好的。反之亦然。工厂似乎更受欢迎。这样做的原因是方便处理私人/公共成员。在这方面,服务将更加笨拙。
在编码Service时,你倾向于通过“this”关键字将对象成员设为public,然后可能突然发现那些public成员对于私有方法(即内部函数)是不可见的。
var Service = function(){
//public
this.age = 13;
//private
function getAge(){
return this.age; //private does not see public
}
console.log("age: " + getAge());
};
var s = new Service(); //prints 'age: undefined'
Angular使用" new "关键字为你创建一个服务,所以Angular传递给控制器的实例也会有同样的缺点。
当然你可以用this/that来解决这个问题:
var Service = function(){
var that = this;
//public
this.age = 13;
//private
function getAge(){
return that.age;
}
console.log("age: " + getAge());
};
var s = new Service();// prints 'age: 13'
但是对于一个大的服务常量this\that-ing会使代码可读性很差。
此外,服务原型不会有private成员,只有public成员可以使用:
var Service = function(){
var name = "George";
};
Service.prototype.getName = function(){
return this.name; //will not see a private member
};
var s = new Service();
console.log("name: " + s.getName());//prints 'name: undefined'
综上所述,使用Factory更加方便。As Factory没有这些缺点。我建议在默认情况下使用它。
即使他们说所有的服务和工厂都是单例的,我也不完全同意。我想说的是,工厂不是单身的,这就是我回答的重点。我真的会考虑定义每个组件的名称(服务/工厂),我的意思是:
A factory because is not a singleton, you can create as many as you want when you inject, so it works like a factory of objects. You can create a factory of an entity of your domain and work more comfortably with this objects which could be like an object of your model. When you retrieve several objects you can map them in this objects and it can act kind of another layer between the DDBB and the AngularJs model.You can add methods to the objects so you oriented to objects a little bit more your AngularJs App.
与此同时,服务是单例的,所以我们只能创建一个,也许不能创建,但当我们注入一个控制器时,我们只有一个实例,所以服务提供更像一个公共服务(休息调用,功能..)到控制器。
从概念上讲,可以像服务提供服务一样,工厂可以创建一个类的多个实例(对象)
与服务相比,没有什么是工厂做不到或做得更好的。反之亦然。工厂似乎更受欢迎。这样做的原因是方便处理私人/公共成员。在这方面,服务将更加笨拙。
在编码Service时,你倾向于通过“this”关键字将对象成员设为public,然后可能突然发现那些public成员对于私有方法(即内部函数)是不可见的。
var Service = function(){
//public
this.age = 13;
//private
function getAge(){
return this.age; //private does not see public
}
console.log("age: " + getAge());
};
var s = new Service(); //prints 'age: undefined'
Angular使用" new "关键字为你创建一个服务,所以Angular传递给控制器的实例也会有同样的缺点。
当然你可以用this/that来解决这个问题:
var Service = function(){
var that = this;
//public
this.age = 13;
//private
function getAge(){
return that.age;
}
console.log("age: " + getAge());
};
var s = new Service();// prints 'age: 13'
但是对于一个大的服务常量this\that-ing会使代码可读性很差。
此外,服务原型不会有private成员,只有public成员可以使用:
var Service = function(){
var name = "George";
};
Service.prototype.getName = function(){
return this.name; //will not see a private member
};
var s = new Service();
console.log("name: " + s.getName());//prints 'name: undefined'
综上所述,使用Factory更加方便。As Factory没有这些缺点。我建议在默认情况下使用它。
可以使用你想要的方式:是否创建对象或只是从两者访问函数
您可以从服务中创建新对象
app.service('carservice', function() {
this.model = function(){
this.name = Math.random(22222);
this.price = 1000;
this.colour = 'green';
this.manufacturer = 'bmw';
}
});
.controller('carcontroller', function ($scope,carservice) {
$scope = new carservice.model();
})
注意:
服务默认返回对象而不是构造函数。
这就是构造函数函数被设为这个的原因。模型属性。
由于此服务将返回对象,但是但是对象内部将是用于创建新对象的构造函数;
您可以从工厂创建新对象
app.factory('carfactory', function() {
var model = function(){
this.name = Math.random(22222);
this.price = 1000;
this.colour = 'green';
this.manufacturer = 'bmw';
}
return model;
});
.controller('carcontroller', function ($scope,carfactory) {
$scope = new carfactory();
})
注意:
Factory默认返回构造函数函数而不是对象。
这就是为什么new object可以用构造函数function创建。
创建只访问简单功能的服务
app.service('carservice', function () {
this.createCar = function () {
console.log('createCar');
};
this.deleteCar = function () {
console.log('deleteCar');
};
});
.controller('MyService', function ($scope,carservice) {
carservice.createCar()
})
创建用于访问简单函数的工厂
app.factory('carfactory', function () {
var obj = {}
obj.createCar = function () {
console.log('createCar');
};
obj.deleteCar = function () {
console.log('deleteCar');
};
});
.controller('MyService', function ($scope,carfactory) {
carfactory.createCar()
})
结论:
您可以使用您想要的方式,无论是创建新对象或
只是为了访问简单的函数
使用其中一种而不是另一种,不会对性能造成任何影响
两者都是单例对象,每个应用程序只创建一个实例。
在每个传递引用的地方都只有一个实例。
在angular文档中,工厂被称为服务,服务也被称为服务。
解释
这里有不同的东西:
第一:
如果你使用一个服务,你将得到一个函数的实例("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原语和函数。”