angular-services - angular.service VS angular.factory

  显示原文与译文双语对照的内容

我看到两个 angular.factory()angular.service() 用于声明服务;然而,我找不到angular.service 在官方文档。

这两种方法的区别是什么? 应该用于什么( 假设他们做了不同的事情)?

时间:


 angular.service('myService', myServiceFunction);
 angular.factory('myFactory', myFactoryFunction);


在我把这个概念放到我自己面前之前,我一直困扰着它:

服务:函数你写将 -ed:


 myInjectedService <---- new myServiceFunction()

工厂 : function (constructor) 你写将调用:


 myInjectedFactory <--- myFactoryFunction()

你所做的事情取决于你,但有一些有用的模式。。

例如编写一个服务函数来公开公共 API:


function myServiceFunction() {
 this.awesomeApi = function(optional) {
//calculate some stuff
 return awesomeListOfValues;
 }
}
---------------------------------------------------------------------------------
//Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();

或者使用工厂的函数公开公共 API:


function myFactoryFunction() {
 var aPrivateVariable ="yay";

 function hello() {
 return"hello mars" + aPrivateVariable;
 }

//expose a public API
 return {
 hello: hello
 };
}
---------------------------------------------------------------------------------
//Injected in your controller
$scope.hello = myInjectedFactory.hello();

或者使用工厂函数返回构造函数:


function myFactoryFunction() {
 return function() {
 var a = 2;
 this.a2 = function() {
 return a*2;
 };
 };
}
---------------------------------------------------------------------------------
//Injected in your controller
var myShinyNewObject = new myInjectedFactory();
$scope.four = myShinyNewObject.a2();


要使用哪一个。

你可以同时完成同样的事情。 然而,在某些情况下,工厂为你提供了更多的灵活性,可以使用更简单的语法。 这是因为当myInjectedService必须是一个对象时,myInjectedFactory可以是一个对象,函数引用或者任何值。 例如如果你编写了一个服务来创建一个构造函数( 如上面的最后一个示例所示),那么它必须像这样实例化:


var myShinyNewObject = new myInjectedService.myFunction()

这可能不太符合以下条件:


var myShinyNewObject = new myInjectedFactory();

(但你应该担心使用这种类型的模式首先因为新 -ing对象控制器创建hard-to-track依赖关系很难模拟进行测试。 使用服务管理对象集合比使用 new() wily-nilly更好。


还有一件事,它们都是单单例。

同时记住,在这两种情况下,Angular 帮助你管理一个单一的。 无论你在哪里注入服务或者函数,你都将得到相同的对象或者函数的相同引用。 ( 除了一个工厂只返回一个数字或者字符串以外的值。 在这种情况下,你将总是得到相同的值,但不是引用。

以下是主要差异:

服务

语法: module.service( 'serviceName', function );

结果:当宣布名作为可注射参数为你提供传递给 module.service 函数的实例。

用途:可以用作分享有用的实用函数调用通过附加 () 注入函数引用。 也可以用 injectedArg.call( this ) 或者类似的方式运行。

工厂

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

结果:当宣布 factoryName作为可注射参数为你提供值调用函数返回的引用传递给 module.factory

用途:可用于返回一个 '类' 函数,可以新创建实例的ed。

同时检查 AngularJS的文档和类似的问题关于 stackoverflow 困惑服务 vs 工厂。

下面是使用服务和工厂列表的示例。 阅读有关 AngularJS服务 vs 工厂的更多信息。

app.factory('fn', fn) vs app.service('fn',fn )

建设

对于工厂,Angular 将调用函数来获得结果。 这就是缓存和注入的结果。


//factory
 var obj = fn();
 return obj;

Angular 将通过调用 。新的调用构造函数。 构造的函数被缓存并注入。


//service
 var obj = new fn();
 return obj;

英镑实现

工厂通常会返回一个对象字面因为返回值注入控制器,模块运行,指示等


 app.factory('fn', function(){
 var foo = 0;
 var bar = 0;
 function setFoo(val) {
 foo = val;
 }
 function setBar (val){
 bar = val;
 }
 return {
 setFoo: setFoo,
 serBar: setBar
 }
 });

服务函数通常不返回任何内容。 相反,它们执行初始化并公开函数。 函数也可以引用'这个',因为它是用'新建'构造的。


app.service('fn', function () {
 var foo = 0;
 var bar = 0;
 this.setFoo = function (val) {
 foo = val;
 }
 this.setBar = function (val){
 bar = val;
 }
});

结论

当使用工厂或者服务时,它们都非常相似。 它们被注入控制器,指令,运行块等,并以几乎相同的方式在客户端代码中使用。 他们也是两个单例对象,这意味着相同的实例之间共享所有地方服务/工厂注入。

那么你更喜欢哪个? 二者都是如此,它们是如此的相似,以至于差异是微不足道的。 如果你选择一个,只是意识到他们是如何构造的,所以你可以正确地实现它们。

服务和工厂在概念上不同。 它们用于不同的东西。 服务用于概念分组的一组函数。 工厂用于创建对象,这些对象可能被分配给作用域并被视为模型。

服务

服务总是单件 。 他们是用来保存概念上的集合分组功能。 你可能有一个服务来与特定的API交互,或者帮助特定的应用程序行为。

因为它们是持久的,你可以使用服务来存储持久数据,例如购物车。

服务是 newable,但你不必像这样使用它们。 一个服务可以简单地编写一个JSON对象并返回它。

下面是一个简单服务的示例,它可以与Github聊天:


angular.module('github', [])
. service('githubService', function( $http ) {
 var service = {
 getEvents: function() {
 var url = 'https://api.github.com/events?callback=JSON_CALLBACK';
 return $http.jsonp(url);
 }
 }
 return service;
 });

工厂

另一方面,工厂用于创建模型。 例如你可以让一个人工厂生成并返回一个人 $resource.


angular.module('app', ['ngResource'])
. controller('authorController', function($scope, $resource, Person) {
 # We can get a person from the factory
 $scope.person = Person.get({ id: 1 });
 # Or compose and save a person
 $scope.newPerson = new Person({
"name":"Mick Johnson",
"email":"mick@example.com"
 })
 $scope.newPerson.$save();
 })
. factory('Person', function($resource) {
 var url = 'http://api.myapp.com/api/v1/people/:id'
 return $resource(url);
 });

在这里,工厂创建一个我们可以在 $scope 中使用并可以选择保存的person对象。

...