AngularJS之Service4
AngularJS之Service(四)
前言
前面我们讲了控制器、过滤器以及指令,这一节我们来讲讲重大内容之一服务和其中涉及到的工厂。
话题
AngularJS中服务可以说是和DI紧密联系在一起,在应用程序中我们可以通过使用服务来共享代码,服务可以被延迟实例化,为何这样说,在Angular内置的服务或者我们自定义的服务只有在注入才能被实例化,同时也就意味着当我们应用程序需要依赖于服务这一组件时才会被实例化,Angular中的服务是一个单例对象即服务中的某一个部分依赖于另外一个服务都会返回从服务工厂中获取到单个实例的引用。Angular中有许多内置默认有用的服务供我们使用,和过滤器一样,我们同样可以根据需求自定义服务。
服务到底做了什么?它的底层实现了什么?它提供了跨领域、请求和操作数据、和外部服务集成以及包括业务逻辑的功能,它简单的就如一个JSON对象。下图给出了Angular组件以及它们之间的作用。

服务到底什么时候应该被创建?为什么要被创建?当我们在应用程序利用Angular需要重用代码时,我们通过服务来封装功能,在Angular模块中有三种方法来定义服务:Factory、Service、Provider。下面我们就这三种方式来创建服务。
Factory method for creating service(推荐方式)
创建服务最简单的方式则是通过module.Factory的方式来创建服务,通过传递两个参数,一个是创建服务的名称,另外一个则是factory函数来返回服务对象。下面我们来创建一个日志记录服务看看。
FactoryService.js
创建factoryApp模块并自定义一个logService服务。

var factroyApp = angular.module('factoryApp', []);
factroyApp.factory('logService', function(){
    var messageCount = 0;
    return {
        log : function(msg){
            console.log("(日志提醒 + " + messageCount++ + ") " + msg);
        }
    };
})

app.js
加载factoryApp依赖模块,通过点击对应的按钮来记录该按钮的文本以及点击的次数。

var app = angular.module('myApp', ['factoryApp']);
app.controller('FactoryController', function ($scope, logService) {
    $scope.data = {
        device: ["Vivo Xplay5", "OPPO R9", "Huawei P9"],
        totalClicks: 0
    };  
    $scope.$watch('data.totalClicks', function (count) {
        logService.log("点击次数: " + count);
    });  
});  
app.directive("triButton", function (logService) {
    return {
        scope: { counter: "=counter" },
        link: function (scope, element, attrs) {
            element.on("click", function (event) {
                logService.log("所点击按钮文本为: " + event.target.innerText);
                scope.$apply(function () {
                    scope.counter++;
                });
            });
        }
    }
});  

FactoryHtml

<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title></title>
<link href="../Content/bootstrap.min.css" rel="stylesheet"/>
<script type="text/javascript" src="../Scripts/angular.min.js"></script>
<script type="text/javascript" src="../Service/FactoryService.js"></script>
<script type="text/javascript" src="../app.js"></script>
</head>
<body ng-controller="FactoryController">
<div class="well">
<div class="btn-group" tri-button counter="data.totalClicks" source="data.device">
<button class="btn btn-default" ng-repeat="item in data.device">
{{item}}
</button>
</div>
<h5>总点击次数: {{data.totalClicks}}</h5>
</div>
</body>
</html>

我们同样来看看结果:

其实对于上述app.js我们完全可以进行改造,通过DI来实现(虽然还未讲到DI)我们可以事先体验一下来得到同样的效果,同时将上述控制器代码进行拆分,这样代码才能一目了然。将app.js中控制器代码改造如下:

app.controller('FactoryController',FactoryController);
app.$inject = ['$scope','logService'];
function FactoryController($scope,logService){
 $scope.data = {
        device: ["Vivo Xplay5", "OPPO R9", "Huawei P9"],
        totalClicks: 0
    };  
    $scope.$watch('data.totalClicks', function (count) {
        logService.log("点击次数: " + count);
    });  
}

Service method for creating service
我们同样可以用service方法来创建服务,但是与上述通过工厂方法来创建服务有点不同,当在AnuglarJS中某一组件需要通过工厂方法定义的服务这一依赖时,很简单只是通过工厂方法返回的对象来使用该对象即可,而在service方法中需要使用服务对象,那么需要将工厂方法作为一个构造函数并且需要使用js关键字来创建这个服务对象,此时这个关键字则不会再在程序中大量使用,则容易造成不必要的麻烦。说了这么多貌似只有用代码才能加深我们的理解,其实就是利用原型继承来创建,我们重新写一个日志服务方法。
上述我们只需要将创建服务的脚本进行改造如下即可:

var serviceApp = angular.module('factoryApp', []);
var baseLogger = function () {
    var messageCount = 0;
    this.log = function (msg) {
       console.log("(日志提醒 + " + messageCount++ + ") " + msg);
    }
};
var debugLogger = function () { };  
debugLogger.prototype = new baseLogger  
serviceApp.service("logService", debugLogger);  

上述代码想必不用做过多解释,再加上第一种方式作为推荐方式,这两种方式作为了解,知道有这三种方式即可。
Provider method for creating service
对于通过这种方式来创建服务我们需要更多的去用代码进行改造,和第一种方式类比,我们通过工厂函数来返回,而对于此方法我们最终需要通过调用$get方法来获取服务对象。代码如下:

var providerApp = angular.module('factoryApp', []);
providerApp.provider("logService", function () {
var messageCount = 0;
    return {
        $get: function () {
            return {
                log: function (msg) {
                    console.log("(日志提醒 + " + messageCount++ + ") " + msg);
                }
            };
        }
    }
});  

总结
这一节我们稍微比较详细的介绍了在AngularJS中如何创建服务,利用三种方式来创建服务,希望对阅读本文的你有所帮助,我们下节再叙。
AngularJS之Service4的更多相关文章
- 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇
		什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ... 
- AngularJs之九(ending......)
		今天继续angularJs,但也是最后一篇关于它的了,基础部分差不多也就这些,后续有机会再写它的提升部分. 今天要写的也是一个基础的选择列表: 一:使用ng-options,数组进行循环. <d ... 
- AngularJS过滤器filter-保留小数,小数点-$filter
		AngularJS 保留小数 默认是保留3位 固定的套路是 {{deom | number:4}} 意思就是保留小数点 的后四位 在渲染页面的时候 加入这儿个代码 用来精确浮点数,指定小数点 ... 
- Angular企业级开发(1)-AngularJS简介
		AngularJS介绍 AngularJS是一个功能完善的JavaScript前端框架,同时是基于MVC(Model-View-Controller理念的框架,使用它能够高效的开发桌面web app和 ... 
- 模拟AngularJS之依赖注入
		一.概述 AngularJS有一经典之处就是依赖注入,对于什么是依赖注入,熟悉spring的同学应该都非常了解了,但,对于前端而言,还是比较新颖的. 依赖注入,简而言之,就是解除硬编码,达到解偶的目的 ... 
- 步入angularjs directive(指令)--点击按钮加入loading状态
		今天我终于鼓起勇气写自己的博客了,激动与害怕并存,希望大家能多多批评指导,如果能够帮助大家,也希望大家点个赞!! 用angularjs 工作也有段时间了,总体感觉最有挑战性的还是指令,因为没有指令的a ... 
- 玩转spring boot——结合AngularJs和JDBC
		参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ... 
- 玩转spring boot——结合jQuery和AngularJs
		在上篇的基础上 准备工作: 修改pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ... 
- 通过AngularJS实现前端与后台的数据对接(一)——预备工作篇
		最近,笔者在做一个项目:使用AngularJS,从而实现前端与后台的数据对接.笔者这是第一次做前端与后台的数据对接的工作,因此遇到了许多问题.笔者在这些问题中,总结了一些如何实现前端与后台的数据对接的 ... 
随机推荐
- ZOJ2971 Give Me the Number 【模拟】
			这道题目使用Map. 然后一次性遍历下来即可. QAQ 注意初始化的时候小心点不要错.. Source Code: //#pragma comment(linker, "/STACK:167 ... 
- QML基础(六篇文章)
			http://www.cnblogs.com/hicjiajia/category/350988.html 
- springmvc中使用response的out.print问题
			public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws E ... 
- Python函数式编程:Lambda表达式
			首先我们要明白在编程语言中,表达式和语句的区别. 表达式是一个由变量.常量.有返回值的函数加运算符组成的一个式子,该式子是有返回值的 ,如 a + 1 就是个表达式, 单独的一个常量.变量 或函数调 ... 
- PHP通过Thrift操作Hbase
			PHP通过Thrift操作Hbase HBase是一个开源的NoSQL产品,它是实现了Google BigTable论文的一个开源产品,和Hadoop和HDFS一起,可用来存储和处理海量col ... 
- 《Java并发编程实战》第十四章 构建自己定义的同步工具 读书笔记
			一.状态依赖性的管理 有界缓存实现的基类 @ ThreadSafe public abstract class BaseBoundedBuffer<E> { @GuardeBy( &quo ... 
- Linux命令: ln
			每天一个linux命令(35):ln 命令 实例1:给文件创建软链接 命令: ln -s log2013.log link2013 输出: [root@localhost test]# ll -rw- ... 
- JSP动态网站环境搭建应用中的详细步骤(Tomcat和Apache/IIS的整合)
			链接地址:http://www.cnblogs.com/dartagnan/archive/2011/03/25/2003426.html JSP动态网站环境搭建应用中的详细步骤(Tomcat和Apa ... 
- 编绎OpenJDK
			因为对于Java里的vtable,itable,有个地方还没搞明白,不得已去下个OpenJDK来研究下. 本来很不愿意去编绎OpenJDK,因为很有可能做的只是无用功,还有可能要去解决各种找不到链接库 ... 
- Windows Azure 安全最佳实践 - 第 7 部分:提示、工具和编码最佳实践
			在撰写这一系列文章的过程中,我总结出了很多最佳实践.在这篇文章中,我介绍了在保护您的WindowsAzure应用程序时需要考虑的更多事项. 下面是一些工具和编码提示与最佳实践: · 在操作系统上运行 ... 
