原文: 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. Deformity ASP/ASPX Webshell、Webshell Hidden Learning

    catalog . Active Server Page(ASP) . ASP.NET . ASP WEBSHELL变形方式 . ASPX WEBSHELL变形方式 . webshell中常见的编码转 ...

  2. QNetworkAccessManager 实现的 ftp 上传

    使用 QNetworkAccessManager 实现的 ftp 上传代码.完整可用,做个备忘. #include "mainwindow.h" #include <QDeb ...

  3. .Net和C#的理解

    .Net是一个微软出品的开发平台,不仅仅是适用于Windows操作系统,还适用于mono,Linux等等, .Net库包括两部分:部分库定义了一些基本类型.CTS(common Type System ...

  4. MVC5-9 今天讲三个Descriptor

    ControllerDescriptor.ActionDescriptor.ParmaterDescriptor 看名字一脸懵逼,这是做什么的呢?可别小看它们,它们在MVC中扮演着尤为重要的角色. 思 ...

  5. python 中的map(), reduce(), filter

    据说是函数式编程的一个函数(然后也有人tucao py不太适合干这个),在我看来算是pythonic的一种写法. 简化了我们的操作,比方我们想将list中的数字都加1,最基本的可能是编写一个函数: I ...

  6. CTO、技术总监、首席架构师的区别

    2016年11月30日13:22:26[转] CTO.技术总监.首席架构师的区别 提升自已的能力,比如专业技术,行业发展趋势,技术发展趋势,协调能力,组织能力,管理能力等[技术总监] 需要从技术总监和 ...

  7. node项目换了环境node_modules各种报错

    依赖文件里,看的出来有些是 ELF 的文件,就是说有些文件是可执行程序,不是拿 js 写的,所以说这部分程序不能适合 Linux .从路径来看,这部分程序的源代码是js写的,但实际调用的是js编译之后 ...

  8. 重新注册iis的.NET Framework版本

    说一个简单的方法,在VS2012.win7 sp1下亲测可用. 在开始菜单中找到VS 2012开发人员命令提示,然后执行命令:aspnet_regiis.exe -i 运行完成后截图如下:

  9. ClassLoader 详解及用途(写的不错)

    ClassLoader主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回 这个类的class对象. 1.1 几个相关概念Clas ...

  10. 9月20日上午JavaScript函数

    函数 一.  函数定义 函数又叫方法,在程序里面函数是用来执行某些特定功能的代码.为了减少重复使用代码,可以把特定功能的代码做成函数,需要使用时拿出来调用.alert();就是一个很常见的.简单的函数 ...