原文: http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html

Service和Factory有什么不同,我应该使用哪个?

这篇文章将讲解service和factory的不同之处,为什么我们喜欢service多过于factory.

Service和Factory的不同之处

在AngularJS中service和factory有什么不同? 我们可以这样定义一个service:

app.service('MyService', function () {
this.sayHello = function () {
console.log('hello');
};
});

.service() 是我们module的一个方法。 有两个参数,第一个参数是服务名,第二个参数是一个function. 可以把Service注入到其他的component中,如controller, directive, filters. 注入方法如下:

app.controller('AppController', function (MyService) {
MyService.sayHello(); // logs 'hello'
});

好了,看看factory是如何做同样的事情的:

app.factory('MyService', function () {
return {
sayHello: function () {
console.log('hello');
};
}
});

.factory() 同样是我们module的一个方法,有两个参数,第一个是factory名,第二个是一个function. 同样factory也可以注入到其他components中. 那么他的不同之处在哪呢?

可以看到在factory中我们没有使用 this , 而是返回一个对象字面量. 为什么这样?因为,service是一个构造函数factory不是. 所以我们在factory的funtion中要显示的返回一个对象.

来看看AngularJS的源代码中的factory函数是怎样的:

function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
}

factory接收一个name, 和factory函数,返回一个同名的provider, $get 是我们的factory函数. 当你获取一个注入,会调用$get()方法向相应的provider请求一个service的实例. 这就是为什么创建provider的时候需要有$get()方法.

换而言之, 当注入MyService时, 后面究竟发生了什么呢:

MyServiceProvider.$get(); // 返回service的实例

现在看看service函数在AngularJS的源代码中是怎么样的:

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

从代码中看得出来,当调用service()的时候实际上最后调用了factory(). 但是没有直接把service的构造函数传给factory. 而是传递了一个依赖injector的函数,通过这个injector去实例化. 简单的说: service调用了预定义的factory, 最后调用相应的provider的$get()方法. $injector.instantiate() 方法最终调用Object.create(),参数为构造函数. 这就是为什么我们要在service里面使用this.

不论我么使用 service() 还是 factory(), 最终都是一个factory,然后这个factory去调用provider.

使用哪一个?

“serivce和factory的不同如下:”

app.service('myService', function() {

  // service是一个构造函数

  this.sayHello = function(name) {
return "Hi " + name + "!";
};
}); app.factory('myFactory', function() { // factory返回一个对象 return {
sayHello : function(name) {
return "Hi " + name + "!";
}
}
});

是的service是一个构造函数, 然后我们一样可以在这个构造函数中返回对象字面量. 事实上, 在javascript中构造函数可以返回任何你想返回的东西. 所以我们把service写得和factory一样:

app.service('MyService', function () {

  // 我们可以在这加入其它的代码
return {
sayHello: function () {
console.log('hello');
};
}
});

现在factory和service的写法已经一样了. 问题是: 我们该使用哪一个呢?

Service能让我们使用ES6的class

在ES6中我们可以这样定义service:

class MyService {
sayHello() {
console.log('hello');
}
} app.service('MyService', MyService);

ES6 class和ES5中的构造函数是一回事.

[译]AngularJS Service vs Factory - Once and for all的更多相关文章

  1. AngularJs:Service、Factory、Provider依赖注入使用与区别

           本教程使用AngularJS版本:1.5.3        AngularJs GitHub: https://github.com/angular/angular.js/       ...

  2. 跟我学AngularJs:Service、Factory、Provider依赖注入使用与差别

    林炳文Evankaka原创作品. 转载请注明出处http://blog.csdn.net/evankaka        本教程使用AngularJs版本号:1.5.3        AngularJ ...

  3. AngularJS 讲解五, Factory ,Service , Provider

    一. 首先说一下,为什么要引入Factory,Service和Provider这三个Service层. 1.因为我们不应该在controller层写入大量的业务逻辑和持久化数据,controller层 ...

  4. 【AngularJS中的自定义服务service VS factory VS provider】---它们的区别,你知道么?

    在介绍AngularJS自定义服务之前,我们先来了解一下AngularJS~ 学过HTML的人都知道,HTML是一门很好的伪静态文本展示设计的声明式语言,但是,要构建WEB应用的话它就显得乏力了. 而 ...

  5. AngularJS进阶(三十三)书海拾贝之简介AngularJS中使用factory和service的方法

    简介AngularJS中使用factory和service的方法 AngularJS支持使用服务的体系结构"关注点分离"的概念.服务是JavaScript函数,并负责只做一个特定的 ...

  6. AngularJS 1.x系列:AngularJS服务-Service、Factory、Provider、Value及Constant(5)

    1. AngularJS服务 AngularJS可注入类型包括:Service.Factory.Provider.Value及Constant. 2. Service AngularJS Servic ...

  7. AngularJS中service,factory,provider的区别(转载:http://my.oschina.net/tanweijie/blog/295067)

    目录[-] 一.service引导 二.service 1.factory() ‍2.service()‍ ‍3.provider()‍‍ 一.service引导 刚开始学习Angular的时候,经常 ...

  8. AngularJS中service,factory,provider的区别

    一.service引导 刚开始学习Angular的时候,经常被误解和被初学者问到的组件是 service(), factory(), 和 provide()这几个方法之间的差别.This is whe ...

  9. 一次性搞明白 service和factory区别

    原文链接 http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html 等下,已经有一篇文 ...

随机推荐

  1. Linux/Windows下如何退出telnet

    [Ctrl+]]->[quit] linux下和windows上一样

  2. subprocess实现管道

    # shell last | cut -d ' ' -f 1 | sort -u #python from subprocess import Popen,PIPE p1 = Popen('last' ...

  3. CentOS关闭火狐浏览器Flash过期提示

    关闭旧版插件屏蔽提示 打开 about:config?filter=extensions.blocklist.enabled 右键切换,关闭flash版本过旧被屏蔽的提示. 参考: http://ti ...

  4. 51nod 1006 最长公共子序列Lcs(经典动态规划)

    传送门 Description 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的).   比如两个串为:   abcicba abdkscab   ab是两个串的子序列,abc也是 ...

  5. POJ 1064 Cable master (二分)

    题目链接: 传送门 Cable master Time Limit: 1000MS     Memory Limit: 65536K 题目描述 有N条绳子,它们长度分别为Li.如果从它们中切割出K条长 ...

  6. 优化DP的奇淫技巧

    DP是搞OI不可不学的算法.一些丧心病狂的出题人不满足于裸的DP,一定要加上优化才能A掉. 故下面记录一些优化DP的奇淫技巧. OJ 1326 裸的状态方程很好推. f[i]=max(f[j]+sum ...

  7. 先贴上代码:Random快排,快排的非递归实现

    设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为主元,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序.值得注意的是, ...

  8. 访问cv::Mat中的数据时遇到的指针类型问题

    在用Opencv的时候由于下图原本的图像尺寸是1111*1111,要进行resize,代码如下: cv::Mat img = cv::imread("//Users//apple//td3/ ...

  9. Java——复选框:JCheckBox

    import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ItemEvent; import java. ...

  10. JavaScript排序算法——希尔排序

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...