AngularJS进阶(四十)创建模块、服务

学习要点

使用模块构架应用

创建和使用服务

为什么要使用和创建服务与模块?

服务允许你打包可重用的功能,使之能在此应用中使用。

模块允许你打包可重用的功能,使之能跨应用使用。

一、应用程序模块化

先看看一个没有模块化的程序

<!DOCTYPE>
<!-- use module -->
<html ng-app="exampleApp">
<head>
    <title>Angluar test</title>
    <meta charset="utf-8"/>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
</head>
<body ng-controller="defaultCtrl">
    <div class="well">
        <!-- 使用自定义指令 -->
        <div class="btn-group" tri-button counter="data.totalClicks">
            <!-- 遍历按钮 -->
            <button class="btn btn-default" ng-repeat="city in data.cities">
                {{city}}
            </button>
        </div>
        <h5>Total Clicks: {{data.totalClicks}}</h5>
    </div>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript">

angular.module("exampleApp", [])
    .controller("defaultCtrl", function ($scope) {
        // 数据模型
        $scope.data = {
            // 城市
            cities : ["London", "New York", "Paris"],
            // 点击总数
            totalClicks : 0
        };
        // 添加监听器,当点击总数发生变化时触发工厂函数
        $scope.$watch("data.totalClicks", function (newVal) {
            console.log("Total click count: " + newVal);
        });
    })
    // 定义指令
    .directive("triButton", function () {
        return {
            // 隔离作用域
            // 双向数据绑定
            scope : {
                counter : "=counter"
            },
            // 链式函数
            link : function (scope, element, attrs) {
                // 点击事件监听,打印日记,计算累加
                element.on("click", function (e) {
                    console.log("Button click: " + e.target.innerText);
                    scope.$apply(function () {
                        scope.counter++;
                    })
                });
            }
        }
    })
</script>
</body>
</html>

单击城市按钮,递增点击总数

接下来,我们将指令分离,使之模块化,我们命名为triButtonDirective.js

angular.module("triButtonDir", [])
    .directive("triButton", function () {
        return {
            // 隔离作用域
            // 双向数据绑定
            scope : {
                counter : "=counter"
            },
            // 链式函数
            link : function (scope, element, attrs) {
                // 点击事件监听,打印日记,计算累加
                element.on("click", function (e) {
                    console.log("Button click: " + e.target.innerText);
                    scope.$apply(function () {
                        scope.counter++;
                    })
                });
            }
        }
    })

接下来,引用定义的标签并且使用它

<!-- 引入指令文件 -->
<script type="text/javascript" src="js/triButtonDirective.js"></script>
<script type="text/javascript">
// 使用指令
angular.module("exampleApp", ["triButtonDir"])

二、创建使用服务

1.使用Factory方法

第一步:将服务模块化,这里创建一个名为triButtonFactory.js的文件

angular.module("triButtonFactory", [])
    .factory("logService", function () {
        var messageCount = 0;
        return {
            log : function (msg) {
                console.log("(Log + " + messageCount++ + ") " + msg);
            }
        }
    })

第二步:在视图中引入该服务

<script type="text/javascript" src="js/triButtonFactory.js"></script>

第三步:在控制器中使用它

// 参数依赖注入
angular.module("exampleApp", ["triButtonDirective", "triButtonFactory"])
    // 作为参数传人控制器中
    .controller("defaultCtrl", function ($scope, logService) {
        // 数据模型
        $scope.data = {
            // 城市
            cities : ["London", "New York", "Paris"],
            // 点击总数
            totalClicks : 0
        };
        // 添加监听器,当点击总数发生变化时触发工厂函数
        $scope.$watch("data.totalClicks", function (newVal) {
            // console.log("Total click count: " + newVal);
            // 使用自定义服务
            logService.log("Total click count: " + newVal);
        });
    })

2.使用Service方法

第一步:创建构造函数,然后创建服务。我们命名为triButtonService.js

var baseLogger = function () {
    this.messageCount = 0;
    this.log = function (msg) {
        console.log(this.msgType + ": " + (this.messageCount++) + " " + msg);
    }
}
var debugLogger = function () {};
debugLogger.prototype = new baseLogger();
debugLogger.prototype.msgType = "Debug";
var errorLogger = function () {};
errorLogger.prototype = new baseLogger();
errorLogger.prototype.msgType = "Error";
angular.module("triButtonService", [])
    .service("logService", debugLogger)

第二步:引入triButtonService.js文件,然后使用服务

<!DOCTYPE>
<!-- use module -->
<html ng-app="exampleApp">
<head>
    <title>Angluar test</title>
    <meta charset="utf-8"/>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
</head>
<body ng-controller="defaultCtrl">
    <div class="well">
        <!-- 使用自定义指令 -->
        <div class="btn-group" tri-button counter="data.totalClicks">
            <!-- 遍历按钮 -->
            <button class="btn btn-default" ng-repeat="city in data.cities">
                {{city}}
            </button>
        </div>
        <h5>Total Clicks: {{data.totalClicks}}</h5>
    </div>
<script type="text/javascript" src="js/angular.min.js"></script>
<!-- 引入指令文件 -->
<script type="text/javascript" src="js/triButtonDirective.js"></script>
<script type="text/javascript" src="js/triButtonService.js"></script>
<script type="text/javascript">
// 使用指令
angular.module("exampleApp", ["triButtonDirective", "triButtonService"])
    .controller("defaultCtrl", function ($scope, logService) {
        // 数据模型
        $scope.data = {
            // 城市
            cities : ["London", "New York", "Paris"],
            // 点击总数
            totalClicks : 0
        };
        // 添加监听器,当点击总数发生变化时触发工厂函数
        $scope.$watch("data.totalClicks", function (newVal) {
            // console.log("Total click count: " + newVal);
            // 使用自定义服务
            logService.log("Total click count: " + newVal);
        });
    })
 </script>
</body>
</html>

3.使用Provider方法

第一步:使用Provider,创建服务。我们命名为triButtonProvider.js

angular.module("triButtonProvider", [])
    .provider("logService", function () {
        var counter = true;
        var debug = true;
        return {
            messageCounterEnabled : function (setting) {
                if (angular.isDefined(setting)) {
                    counter = setting;
                    return this;
                } else {
                    return counter;
                }
            },
            debugEnabled : function (setting) {
                if (angular.isDefined(setting)) {
                    debug = setting;
                    return this;
                } else {
                    return debug;
                }
            },
            // 用于返回服务对象
            $get : function () {
                return {
                    messageCount : 0,
                    log : function (msg) {
                        if (debug) {
                            console.log("(LOG" + (counter ? " + " + this.messageCount++ + ") " : ") " + msg));
                        }
                    }
                }
            }
        }
    })

第二步:引入、配置和使用服务

<!DOCTYPE>
<!-- use module -->
<html ng-app="exampleApp">
<head>
    <title>Angluar test</title>
    <meta charset="utf-8"/>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
</head>
<body ng-controller="defaultCtrl">
    <div class="well">
        <!-- 使用自定义指令 -->
        <div class="btn-group" tri-button counter="data.totalClicks">
            <!-- 遍历按钮 -->
            <button class="btn btn-default" ng-repeat="city in data.cities">
                {{city}}
            </button>
        </div>
        <h5>Total Clicks: {{data.totalClicks}}</h5>
    </div>
<script type="text/javascript" src="js/angular.min.js"></script>
<!-- 引入指令文件 -->
<script type="text/javascript" src="js/triButtonDirective.js"></script>
<script type="text/javascript" src="js/triButtonProvider.js"></script>
<script type="text/javascript">
// 使用指令
angular.module("exampleApp", ["triButtonDirective", "triButtonProvider"])
    // 使提供强对象适用于依赖注入,服务器 + Provider = logServiceProvider
    .config(function (logServiceProvider) {
        logServiceProvider.debugEnabled(true).messageCounterEnabled(false);
    })
    .controller("defaultCtrl", function ($scope, logService) {
        // 数据模型
        $scope.data = {
            // 城市
            cities : ["London", "New York", "Paris"],
            // 点击总数
            totalClicks : 0
        };
        // 添加监听器,当点击总数发生变化时触发工厂函数
        $scope.$watch("data.totalClicks", function (newVal) {
            // console.log("Total click count: " + newVal);
            // 使用自定义服务
            logService.log("Total click count: " + newVal);
        });
    })
</script>
</body>
</html>

美文美图



AngularJS进阶(四十)创建模块、服务的更多相关文章

  1. 网站开发进阶(四十四)input type="submit" 和"button"的区别

    网站开发进阶(四十四)input type="submit" 和"button"的区别   在一个页面上画一个按钮,有四种办法: 这就是一个按钮.如果你不写ja ...

  2. Java进阶(四十)Java类、变量、方法修饰符讲解

    Java进阶(四十)Java类.变量.方法修饰符讲解 Java类修饰符 abstract: 将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现. final: 将一个类生命为最终(即非继承类) ...

  3. 网站开发进阶(四十二)巧用clear:both

    网站开发进阶(四十二)巧用clear:both 前言 我们在制作网页中用div+css或者称xhtml+css都会遇到一些很诡异的情况,明明布局正确,但是整个画面却混乱起来了,有时候在IE6下看的很正 ...

  4. Java进阶(四十二)Java中多线程使用匿名内部类的方式进行创建3种方式

    Java中多线程使用匿名内部类的方式进行创建3种方式 package cn.edu.ujn.demo; // 匿名内部类的格式: public class ThreadDemo { public st ...

  5. AngularJS进阶(三十二)书海拾贝之特殊的ng-src和ng-href

    书海拾贝之特殊的ng-src和ng-href 在说明这两个指令的特殊之前,需要先了解一下ng的启动及执行过程,如下: 1) 浏览器加载静态HTML文件并解析为DOM: 2) 浏览器加载angular. ...

  6. AngularJS进阶(三十四)Angular数据更新不及时问题探讨

    Angular数据更新不及时问题探讨 前言 在修复控制角标正确变化过程中,发觉前端代码组织层次出现了严重问题.传递和共享数据时自己使用的是rootScope,为此造成了全局变量空间的污染.根据< ...

  7. AngularJS进阶(二十四)AngularJS与单选框及多选框的双向动态绑定

    AngularJS与单选框及多选框的双向动态绑定      赠人玫瑰,手留余香.若您感觉此篇博文对您有用,请花费2秒时间点个赞,您的鼓励是我不断前进的动力,共勉! AngularJS 在 <in ...

  8. AngularJS进阶(二十五)requirejs + angular + angular-route 浅谈HTML5单页面架构

    requirejs + angular + angular-route 浅谈HTML5单页面架构 众所周知,现在移动Webapp越来越多,例如天猫.京东.国美这些都是很好的例子.而在Webapp中,又 ...

  9. AngularJS进阶(三十六)AngularJS项目开发技巧之利用Service&Promise&Resolve解决图片预加载问题(后记)

    AngularJS项目开发技巧之利用Service&Promise&Resolve解决图片预加载问题(后记) 前言 在"AngularJS项目开发技巧之图片预加载" ...

随机推荐

  1. Why Helm? - 每天5分钟玩转 Docker 容器技术(160)

    本章我们将学习 Helm,Kubernetes 的包管理器. 每个成功的软件平台都有一个优秀的打包系统,比如 Debian.Ubuntu 的 apt,Redhat.Centos 的 yum.而 Hel ...

  2. 天梯赛-L1-018. 大笨钟

    L1-018. 大笨钟 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 微博上有个自称"大笨钟V"的家伙,每 ...

  3. 使用gogs搭建git私有仓库

    搭建gogs 我的机器环境:centos 7 1.安装git yum install git   2.安装mysql gogs的数据存在mysql中,需要安装一个mysql来存数据,当然也有其他的选择 ...

  4. 【图文详解】Hadoop集群搭建(CentOs6.3)

    本文主要详细地描述了hadoop集群的搭建以及一些配置文件的说明,用于自己复习以及供新人学习,若有错误之处还请指出. 前期准备 先给出我的集群架构: 到hadoop官网下载好hadoop安装包http ...

  5. 初步配置阿里云ECS服务器

    阿里云服务器配置记录01 购买阿里云学生服务器9.9元每月 创建ubuntu64位实例系统,注意必须添加安全组设置才可远程登入(设置课访问端口及IP范围 putty 软件在windows10下远程登入 ...

  6. Java常用集合学习总结

    一  数组 数组可以存储基本数据类型和对象的一种容器,长度固定,所以不适合在对象数量未知的情况下使用. Arrays : 用于操作数组对象的工具类,里面都是静态方法. Arrays.asList:把A ...

  7. 使用DB查询分析器实现异构数据源中数据表的相互访问

    1  引言   硕士程序员马根峰(CSDN专访马根峰:海量数据处理与分析大师的中国本土程序员)推出的个人作品----万能数据库查询分析器,中文版本DB 查询分析器.英文版本<DB Query A ...

  8. Android音频焦点处理相关的方法

    有这么一种场景:你打开qq音乐.优酷客户端.视频播放的时候.这个时候突然来电显示了,此时所有的MediaPlayer相关的服务或者响应都进入"休眠"状态.那么,这个功能是怎么实现的 ...

  9. python数据挖掘orange

    http://blog.csdn.net/pipisorry/article/details/52845804 orange的安装 linux下的安装 先安装依赖pyqt4[PyQt教程 - pyth ...

  10. Android通知Notification全面剖析

    通知 通知是您可以在应用的常规 UI 外部向用户显示的消息.当您告知系统发出通知时,它将先以图标的形式显示在通知区域中.用户可以打开抽屉式通知栏查看通知的详细信息. 通知区域和抽屉式通知栏均是由系统控 ...