当你初试 Angular 时,很自然地就会往 controller 和 scope 里堆满不必要的逻辑。一定要早点意识到,controller 这一层应该很薄;也就是说,应用里大部分的业务逻辑和持久化数据都应该放在 service 里。我每天都会在 Stack Overflow 上看到几个同类的问题,关于如何在 controller 里保存持久化数据。这就不是 controller 该干的事。出于内存性能的考虑,controller 只在需要的时候才会初始化,一旦不需要就会被抛弃。因此,每次当你切换或刷新页面的时候,Angular 会清空当前的 controller。与此同时,service 可以用来永久保存应用的数据,并且这些数据可以在不同的 controller 之间使用。

Angular 提供了3种方法来创建并注册我们自己的 service。

  1. Factory

  2. Service

  3. Provider

  4. 如果你是“太长的不看”

    1) 用 Factory 就是创建一个对象,为它添加属性,然后把这个对象返回出来。你把 service 传进 controller 之后,在 controller 里这个对象里的属性就可以通过 factory 使用了。

    2) Service 是用"new"关键字实例化的。因此,你应该给"this"添加属性,然后 service 返回"this"。你把 service 传进 controller 之后,在controller里 "this" 上的属性就可以通过 service 来使用了。

  5. 现在让我们向回调函数中添加一些“private” 变量。当然 controller中是无法直接访问这些变量的,不过我们最终还是会在“service”中设置setter和个getter 方法,以便必要时修改这些“private”变量。

    你可能注意到了,我们没有将变量/函数加到“service”中。我们只是简单的创建他们以便之后的使用和修改。

    •  baseUrl 是iTunes API要求的根URL

    •  _artist 是我们想要查找的艺术家

    • _finalUrl 是最终的权限定URL,即我们调用iTunes的入口

    • makeUrl 是一个创建并返回友好的iTunesURL的函数

    既然我们的帮手/私有变量和函数放在的合适的位置,那么让我们向“service”对象中添加一些属性。无论我们向”service“中添加什么, 我们都能在任意一个我们传递进‘myFactory’ 的controller中使用。

  6. 现在让我们向回调函数中添加一些“private” 变量。当然 controller中是无法直接访问这些变量的,不过我们最终还是会在“service”中设置setter和个getter 方法,以便必要时修改这些“private”变量。

    你可能注意到了,我们没有将变量/函数加到“service”中。我们只是简单的创建他们以便之后的使用和修改。

    •  baseUrl 是iTunes API要求的根URL

    •  _artist 是我们想要查找的艺术家

    • _finalUrl 是最终的权限定URL,即我们调用iTunes的入口

    • makeUrl 是一个创建并返回友好的iTunesURL的函数

    既然我们的帮手/私有变量和函数放在的合适的位置,那么让我们向“service”对象中添加一些属性。无论我们向”service“中添加什么, 我们都能在任意一个我们传递进‘myFactory’ 的controller中使用。

  7. 现在我们的factory完成了。我们可以将"myFactory"注入到任意controller中了,然后就可以调用我们添加到service对象中的方法了(setArtist,getArtist,和callItunes)。

    在上面的controller中,我们注入了‘myFactory’ service对象。然后我们设置$scope 对象的属性。上面唯一棘手的代码是处理promise。因为callItunes返回一个promise对象,一旦我们的promise满足了,我们可以调用.then()方法以及设置$scope.data.artistData。你会注意到我们的controller是非常的“瘦”。因为我们所有的逻辑和持久化数据都存放在了service中而不是controller中。

  8.  Service

    当我们创建一个Service时,我们所知道的最重要事可能就是Service通过new关键字实例化对象。这应该可以使熟悉JavaScript的人了解到了这段代码的作用。但对于那些JS背景有限,或者不太熟悉new关键字的作用的人来说可能有点困难。那就让我们来重温一下JavaScript的基本功能,以便帮助我们了解Service究竟做了什么。

    让我们先定义一个函数,然后通过new关键字来调用它,看看当解释器遇到了new关键字的时候做了些什么工作,以便帮助我们了解使用new关键字来实例化一个函数时究竟有什么变化。这个的最终结果应该和Service是一样的。

  9. 首先,让我们定义一个构造器。

    这个一个典型的JavaScript式的构造方法。现在,只要我们使用new关键字来调用Person函数,就会将'this'关键字绑定到新创建的对象上。

    接下来,让我们给Person的prototype对象添加一个方法,这个方法对所有Person ‘类’的实例都是可用的。

    现在,由于我们往prototype上添加了一个sayName方法,所以所有的Person实例都可以调用这个方法,并且输出对应实例的name值。

    既然我们已经有了一个Person的构造器,并在在其prototype上定义了一个sayName方法,那就让我们去创建一个Person的实例,并调用这个sayName方法。

    接下来,我们把创建Person构造器、往其prototype上添加方法、创建一个Person实例,并调用sayName方法的代码写在一块,如下所示:

  10. 现在,让我们看一下当我们在JavaScript中使用new关键字的时候究竟发生了什么。首先你应该已经注意到的是,当我们在例子中使用了new关键字之后,我们可以通过'tyler'来调用方法(sayName),看上去好像tyler是一个对象——那是因为它确实成了一个对象。所以,我们知道的第一件事就是我们的Person构造器返回了一个对象(object)。其次,我们知道,由于我们的sayName方法是定义在Person的prototype上,而不是直接定义在Person的实例上的,所以Person函数返回的对象(tyler)一定是由于未找到sayName方法,进而去prototype寻找sayName方法的。用更通俗的话来说,当我们调用tyler.sayName()时,JS解释器说,“好吧,我先去我们刚创建的'tyler'对象上查找sayName方法,然后调用它。等一下,我没有在它上面找到sayName方法——我只看到了name和age,那让我去prototype找一下吧。没错,它在prototype上,那就让我调用它吧”。

    下面的代码演示了在JavaScript中使用new关键之后所做的事。它是上面这一段文字的一个基本的代码示例。我已经把从JS解释器的角度来看整个过程的代码写在了注释里。

  11. 现在,既然我们了解了在JavaScript中new关键字是如何工作的,那么在Angular中创建一个Service也应该变得容易理解了。

    在创建一个Service时,需要理解的最重要的一件事就是我们使用new关键字去实例化Service对象。结合我们从上面的例子所了解到的知识,你应该已经意识到你可以将一些属性和方法直接添加到this上,之后,在创建Service对象时,this会被作为返回值返回。让我们来看一下这种工作方式。

    我们不用像之前Factory中的例子那样创建一个对象,然后返回这个对象。因为我们使用了new关键字来调用,解释器会创建一个对象,并关联它的prototype对象,然后将该对象返回,而不用我们去做这些工作。

  12.  Provider

    要记住的关于Provider的最重要的事情是,它们是你可以传递到应用程序的app.config部分唯一的服务。如果你需要在你的服务对象可以在你的应用程序之外任何地方都可用之前改变它的某些部分,这是非常重要的。虽然Services/Factories很相似,但也有一些差异,我们将会讨论它们。

    首先,我们用与我们建立Service 和 Factory类似的方式来建立我们的Provider。下面的变量是我们的'私人'和辅助功能。

    *同样地,如果上面的代码的任何部分令你纠结,请看下 Factory 部分,在那里我更详细地解释了这些代码的作用。

  13. 必须要注意的一点是只有这些变量和函数是可以在我们的app.config函数中访问的。这曾一度使我感到困惑,所以你最好也要知道这点不同之处。你可以把Provider想象成由两部分组成。第一部分的变量和函数是可以在app.config函数中访问的,因此你可以在它们被其他地方访问到之前来修改它们(如上所示)。第二部分(如下所示) 的变量和函数是可以在任何传入了’myProvider‘的控制器中进行访问的。

    当你使用Provider创建一个service时,唯一的可以在你的控制器中访问的属性和方法是通过$get()函数返回内容。下面的代码将$get方法写在了’this‘(最终会被函数返回)上。现在,$get函数会返回所有我们希望在控制器中进行访问的方法和属性。下面是代码示例:

  14. 现在,Provider的完整代码如下所示:

    现在,与我们的Factory和Service类似,setArtist, getArtist, 和callItunes可以在任何一个传入了 myProvider 的控制器中访问。下面是myProvider的控制器(几乎和我们Factory/Service中的控制器一样)。

    正如前面提到的那样,使用Provider创建一个service的独特之处是,你可以在Provider对象传递到应用程序的其他部分之前在app.config函数对其进行修改。让我们来看一个对应的例子。

  15. 现在你可以明白‘thingFromConfig’是怎么样地在我们的provider中是空字符串,而当它出现在DOM中时,它将是'This sentence was set…’。

AngularJS 之 Factory、Service、Provider的更多相关文章

  1. angularjs 中 Factory,Service,Provider 之间的区别

    本片文章是使用了 angularjs 中使用 service 在controller 之间 share 对象和数据 的code(http://jsfiddle.net/kn46u0uj/1/) 来进行 ...

  2. angularjs factory,service,provider 自定义服务的不同

    angularjs框架学了有一段时间了,感觉很好用.可以把angularjs的app理解成php的class,controller是控制器,而内置服务和自定义服务就可以理解成models了.angul ...

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

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

  4. [译]AngularJS中几种Providers(Factory, Service, Provider)的区别

    原文: http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/ 什么是Provider? Angula ...

  5. angularjs中factory, service和provider

    在Angular里面,services作为单例对象在需要到的时候被创建,只有在应用生命周期结束的时候(关闭浏览器)才会被清除.而controllers在不需要的时候就会被销毁了(因为service的底 ...

  6. AngularJS Factory Service Provider

    先看看http://www.cnblogs.com/mbydzyr/p/3460501.html http://www.oschina.net/translate/angularjs-factory- ...

  7. angula的factory service provider

    本人学了一段时间的angular的服务(factory.service.provider),有了自己的一些对于他们的见解,如果说的对,敬请赐教!!! 以后更新

  8. AngularJS 之 Factory vs Service vs Provider【转】

    英文原文:AngularJS: Factory vs Service vs Provider 当你初试 Angular 时,很自然地就会往 controller 和 scope 里堆满不必要的逻辑.一 ...

  9. angularJs 解析factory、service、provider

    了解angular js factory可以认为是设计模式中的工厂方法,就是你提供一个方法,该方法返回一个对象的实例:对于angularJs的factory,就是先定义一个对象,给这个对象添加属性和方 ...

随机推荐

  1. BZOJ 1419: Red is good

    Sol 期望DP. \(f[i][j]\) 表示剩下 \(i\) 张红牌, \(j\) 张黑牌的期望. 有转移方程. \(f[i][j]=0,i=0\) 没有红色牌了,最优方案就是不再翻了. \(f[ ...

  2. 深入浅出Mybatis-与Spring集成

    单独使用mybatis是有很多限制的(比如无法实现跨越多个session的事务),而且很多业务系统本来就是使用spring来管理的事务,因此mybatis最好与spring集成起来使用. 前置要求 版 ...

  3. PHP javascript cookie

    2015-07-30 16:54:58 ................................cao!!!! 汉字, 邮箱的@符号 容易出错 PHP setcookie 的时候, 不要url ...

  4. vs2013 控制台程序exe图标

    工程右击选择添加resource->Icon. 在工程目录就会生成  工程名.rc 和 XX.ico文件. 重新编译程序,就会生成有图标的exe. 对应的配置在  工程名.rc  文件里,用记事 ...

  5. Zookeeper集群服务部署

    Zookeeper是一个分布式.开源的分布式应用程序协调服务,是Google的Chubby的开源实现,也是和Hadoop.Hbase相互配合的重要组件,作用就是为分布式应用程序提供一致性服务,包括配置 ...

  6. Java for LeetCode 209 Minimum Size Subarray Sum

    Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...

  7. poj 2389.Bull Math 解题报告

    题目链接:http://poj.org/problem?id=2389 题目意思:就是大整数乘法. 题目中说每个整数不超过 40 位,是错的!!!要开大点,这里我开到100. 其实大整数乘法还是第一次 ...

  8. code vs1436 孪生素数 2(数论+素数的判定)

    1436 孪生素数 2  时间限制: 2 s  空间限制: 1000 KB  题目等级 : 白银 Silver 题解  查看运行结果     题目描述 Description 如m=100,n=6 则 ...

  9. 【leetcode】Remove Nth Node From End of List(easy)

    Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...

  10. 【leetcode】Search in Rotated Sorted Array (hard)

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...