我们在上一篇《[JavaScript从入门到放弃] AngularJS篇 1.AngularJS不入门》中简单的介绍了AngularJS的基础使用。我们在最后留了个问题,当页面功能变得复杂时,代码都在控制器中显然会变得很臃肿。我们在Java项目中,一般都是分层,比如搞个Service层。
概念
好,我们来看下在ng中是怎么使用Service,也就是服务的。
服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性。 服务是个单例对象,在每个应用中只会被实例化一次。并且是懒加载的,在被需要时才会被创建。服务负责提供把与特定功能相关联的方法集中在一起的接口。——《AngularJS权威教程》
使用
创建服务有5种方式,我们这里只介绍简单常用的一种。
既然是服务层,显然要定义个单独的模块。
在controller中使用时要先引用这个服务层,在哪引用,当然是UI层
这第二个参数是个数组,说明可以引用多个服务层,专业名称被称为依赖。 我们再看下如何在controller中访问。
这时候你看到了,把服务对象放到参数中,$http其实也是ng内置的一个服务。
而且我们知道,$http是用来获取后台数据的。显然不应该放在controller层中,应该放到service层中。 所以我们要改造一下上一篇中的代码:
OK,运行一下,我们发现没有任何卵用,列表并没有加载出来。难道是没有执行?我们看下浏览器控制台:
发现其实http是请求了的。
那问题出在哪呢?此时我们敏锐的想到,是不是因为ajax是异步的。服务在ajax数据还没返回的时候,直接return了。 我们一下,发现果然数据是空的。
那说明确实是因为异步导致的。那怎么办呢?我们尝试一下在JQuery中的做法,把return 放到ajax的回调方法中:
这样看起来万无一失了。运行一下,直接报错:
为啥?显然ng中的fuction已经不是普通的js中的function了。必须像在Java一样,无论如何必须有个显式的返回,而不能再某个分支中做返回。
那咋办呢?我们尝试一下,像之前学的NodeJS一样,传个回调函数试试。
目前这样写不是特别好,因为这个服务就很单一了,只能返回个fuction。我们更希望她能返回个对象,所以我们可以再改一下:
这样就差不多了。
强行的拉到数据了。但回调函数始终都是个坎,好多新人不会写JS插件都是因为对回调函数感动绕。其实难度不是很大,我们理解一下。我们在服务中返回了一个fuctionA,同时这个fuctionA接收一个fuctionB参数,然后在functionA中的ajax请求完成后执行functionB,这个functionB呢接收个object参数,我们可以把ajax的返回值放进去。这样我们就可以在controller层中自定义处理了。
调用一下fuctionA(),然后传入一个自定义function,然后这个自定义function中的参数就是ajax请求到的数据了。
还是很绕?而且可读性不是特别好。用我学生的话说,第一篇入门,第二篇放弃。。。
其实回调最大的弊端就是篡改了代码的流程,使得代码调试和阅读都变得困难,而且当某个回调依赖于其他回调时,就越发困难了,数据完整性得不到保证。当出现Exception异常时,就完犊子了。
ng对此提供了一个叫promise的对象来处理异步数据返回的问题。她代表了一个函数最终可能的返回值或者抛出的异常。
听起来有点迷糊?我们来重新改造一下之前的例子就知道咋办了。
$http.get()会返回个promise对象,then()之后又会返回promise对象,有点像JQ的链式调用,总之就是一直then到死。。。
这样可以让我们脱离回调陷阱了,代码的逻辑也变得清晰起来。
$resource
ng中的$http其实就是非常简单的将js中的ajax封装了一下,其实ng还提供了一个更有趣的http服务,叫$resource。 要使用$resource服务,需要单独安装ngResource模块,地址可以在BootCDN找。
使用时也要引用依赖:
$resource封装了多个同后端服务器交互的API。让我们访问数据变得更简单,除了get方法之外,还有query方法,主要区别是前者是获取对象,后者是获取数组。除了获取数据,有时候我们也要提交数据。ng中提供了对应的save/remove方法。
要注意$resource是异步的:
一般我们都是使用自定义的$resource方法,也就是创建实例时传第三个参数:
大家喜欢$http还是$resource,请自己选择吧。
今天就这样吧。溜了溜了。
最后依然是简单的软广:
如果有朋友想学编程,请联系我,稳。
有编程上的交流也可以一起讨论,共同进步。
看完不转发吗?
领取专属 10元无门槛券
私享最新 技术干货