原文: 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. PowerDesigner设计表时显示注释选项

    选定编辑的表,[右键]->[Properties]->[Columns]->[Customize Columns and Filter]->[Comment]->[OK] ...

  2. 百度地图学习(II)-Android端的定位

    哎,经历了小编的最近时间的研究,我的百度定位终于成功啦,刹那间觉得自己萌萌哒啦(- ̄▽ ̄)- 话不多说,直接进入正题: 首先,我们来看一下效果: [分析定位原理] [编码分析] 1)处理程序的清单文件 ...

  3. 控件的invoke和beginInvoke方法

    System.Windows.Forms.Timer 的timer是在主线程上执行的,因此在timer的tick事件中操作界面上的控件不会发生线程的安全性检测. Control的invoke和begi ...

  4. MACOS 答题器,界面跳转

    国内OSX开发的资料实在少,甚至连一本开发的书都找不到… 更无语的是,苹果自家的开发文档Sample Code不仅还停留在OC版本,还是MRC的… 在这样的情况下,OSX开发还真得靠“想象力”… 网上 ...

  5. Centos下查看占用端口并关闭进程方法

    1.查看端口占用情况:netstat –tlnp   (加p可以看到是哪个进程占用了端口); 也可以用grep查找对应的被占用的端口,键入netstat –tlnp | grep 3306可以看到PI ...

  6. HDU 1166 敌兵布阵(线段树模板题)

    题目链接: 传送门 敌兵布阵 Time Limit: 2000MS     Memory Limit: 32768 K Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头 ...

  7. 《JavaScript权威指南》学习笔记 第五天 window对象的方法。

    前天和昨天大致浏览了犀牛书的函数.类与模块.正则表达式.JavaScript扩展.以及服务端的js.这些方面对于我目前的水平来说比较难,一些最基本的概念都不能领会.不过最复杂的知识占用平时使用的20% ...

  8. MyEclipse取消自动跳到Console窗口

    在Myeclipse中当全屏查看其它文件时,如果控制台有东西输出,就会弹出控制台窗口,如何取消? 方法1: -->右键在console窗口中点Preferences, -->将Show w ...

  9. C#--之文件操作

    1.从文本文件中读取一行文本 StreamReader sr = new StreamReader("C:\\1.txt"); string readline = sr.ReadL ...

  10. 修改美化Matlab字体

    修改美化Matlab字体    MATLAB作为高校理工科类本科生或研究生必不可少的科研工具已经有着很多年的历史,以至于在我们的大学生活里或科研工作中,MATLAB处处闪现着它的身影,给我们带来了不少 ...