AngularJS Module方法详解


Posted in Javascript onDecember 08, 2015

AngularJS是什么?

AngularJs(后面就简称ng了)是一个用于设计动态web应用的结构框架。首先,它是一个框架,不是类库,是像EXT一样提供一整套方案用于设计web应用。它不仅仅是一个javascript框架,因为它的核心其实是对HTML标签的增强。

何为HTML标签增强?其实就是使你能够用标签完成一部分页面逻辑,具体方式就是通过自定义标签、自定义属性等,这些HTML原生没有的标签/属性在ng中有一个名字:指令(directive)。后面会详细介绍。那么,什么又是动态web应用呢?与传统web系统相区别,web应用能为用户提供丰富的操作,能够随用户操作不断更新视图而不进行url跳转。ng官方也声明它更适用于开发CRUD应用,即数据操作比较多的应用,而非是游戏或图像处理类应用。

为了实现这些,ng引入了一些非常棒的特性,包括模板机制、数据绑定、模块、指令、依赖注入、路由。通过数据与模板的绑定,能够让我们摆脱繁琐的DOM操作,而将注意力集中在业务逻辑上。

  另外一个疑问,ng是MVC框架吗?还是MVVM框架?官网有提到ng的设计采用了MVC的基本思想,而又不完全是MVC,因为在书写代码时我们确实是在用ng-controller这个指令(起码从名字上看,是MVC吧),但这个controller处理的业务基本上都是与view进行交互,这么看来又很接近MVVM。让我们把目光移到官网那个非醒目的title上:“AngularJS — Superheroic JavaScript MVW Framework”。

AngularJS中的Module类负责定义应用如何启动,它还可以通过声明的方式定义应用中的各个片段。我们来看看它是如何实现这些功能的。

一.Main方法在哪里

        如果你是从Java或者Python编程语言转过来的,那么你可能很想知道AngularJS里面的main方法在哪里?这个把所有东西启动起来,并且第一个被执行的方法在哪里?JavaScript代码里面负责实例化并且把所有东西组合到一起,然后命令应用开始运行的那个方法在哪里?

        事实上,AngularJS并没有main方法,AngularJS使用模块的概念来代替main方法。模块允许我们通过声明的方式来描述应用中的依赖关系,以及如何进行组装和启动。使用这种方式的原因如下:

        1.模块是声明式的。这就意味着它编写起来更加容易,同时理解起来也很容易,阅读它就像读普通的英文一样!

        2.它是模块化的。这就迫使你去思考如何定义你的组件和依赖关系,让它们变得更加清晰。

        3.它让测试更加容易。在单元测试吕,你可以有选择地加入模块,并且可以避免代码中存在无法进行单元测试的内容。同时,在场景测试中,你可以加载其他额外的模块,这样就可以更好地和其他组件配合使用。

        例如,在我们的应用中有一个叫做"MyAwesomeApp"的模块。在HTML里面,只要把以下内容添加到<html>标签中(或者从技术上说,可以添加到任何标签中):

<html ng-app="MyAwesomeApp">

 ng-app指令就会告诉AngularJS使用MyAwesomeApp模块来启动你的应用。那么,应该如何定义模块呢?举例来说,我们建议你为服务、指令和过滤器分别定义不同的模块。然后你的主模块可以声明依赖这些模块。

        这样可以使得模块管理更加容易,因为它们都是良好的、完备的代码块,每个模块有且只有一种职能。同时,单元测试可以只加载它们所关注的模块,这样就可以减少初始化的次数,单元测试也会变得更精致、更专注。

二.加载和依赖

        模块加载动作发生在两个不同的阶段,这一点从函数名上面就可以反映出来,它们分别是Config代码块和Run代码块(或者叫做阶段)。

1.Config代码块

        在这一阶段里面,AngularJS会连接并注册好所有数据源。因此,只有数据源和常量可以注入到Config代码块中。那些不确定是否已经初始化好的服务不能注入进来。

2.Run代码块

        Run代码块用来启动你的应用,并且在注射器创建完成之后开始执行。为了避免在这一点开始之后再对系统进行配置操作,只有实例和常量可以被注入到Run代码块中。你会发现,在AngularJS中,Run代码块是与main方法最类似的东西。

三.快捷方法

        利用模块可以做什么呢?我们可以用它来实例化控制器、指令、过滤器以及服务,但是利用模块类还可以做更多事情。如下模块配置的API方法:

1.config(configFn)

        利用此方法可以做一些注册工作,这些工作需要在模块加载时完成。

2.constant(name, object)

        此方法会首先运行,所以你可以用它来声明整个应用范围内的常量,并且让它们在所有配置(config方法)和实例(后面的所有方法,例如controller、service等)方法中可用。

3.controller(name,constructor)

        它的基本作用是配置好控制器方便后面使用。

4.directive(name,directiveFactory)

        可以使用此方法在应用中创建指令。

5.filter(name,filterFactory)

        允许你创建命名的AngularJS过滤器,就像前面章节所讨论的那样。

6.run(initializationFn)

        如果你想要在注射器启动之后执行某些操作,而这些操作需要在页面对用户可用之前执行,就可以使用此方法。

7.value(name,object)

        允许在整个应用中注射值。

8.factory(name,factoryFn)

        如果你有一个类或者对象,需要首先为它提供一些逻辑或者参数,然后才能对它初始化,那么你就可以使用这里的factory接口。factory是一个函数,它负责创建一些特定的值(或者对象)。我们来看一个greeter(打招呼)函数的实例,这个函数需要一条问候语来初始化:

function Greeter(salutation) {
 this.greet = function(name) {
 return salutation + ' ' + name;
};
}

 greeter函数示例如下:

myApp.factory('greeter', function(salut) {
 return new Greeter(salut);
});

 然后可以这样来调用它:

var myGreeter = greeter('Halo');

9.service(name,object)

        factory和service之间的不同点在于,factory会直接调用传递给它的函数,然后返回执行的结果;而service将会使用"new"关键字来调用传递给它的构造方法,然后再返回结果。所以,前面的greeter Factory可以替换成下面这个greeter Service:

myApp.service('greeter', Greeter);

 每当我们需要一个greeter实例的时候,AngularJS就会调用新的Greeter()来返回一个实例。

10.provider(name,providerFn)

        provider是这几个方法中最复杂的部分(显然,也是可配置性最好的部分)。provider中既绑定了factory也绑定了service,并且在注入系统准备完毕之前,还可以享受到配置provider函数的好处(也就是config块)。

        我们来看看使用provider改造之后的greeter Service是什么样子:

myApp.provider('greeter', function() {
 var salutation = 'Hello';
 this.setSalutation = function(s) {
 salutation = s;
}
 function Greeter(a) {
 this.greet = function() {
 return salutation + ' ' + a;
}
}
 this.$get = function(a) {
 return new Greeter(a);
};
});

这样我们就可以在运行时动态设置问候语了(例如,可以根据用户使用的不同语言进行设置)。

var myApp = angular.module(myApp, []).config(function(greeterProvider) {
greeterProvider.setSalutation('Namaste');
});
Javascript 相关文章推荐
网页打开自动最大化的js代码
Aug 22 Javascript
将光标定位于输入框最右侧实现代码
Dec 04 Javascript
给ListBox添加双击事件示例代码
Dec 02 Javascript
jquery中trigger()无法触发hover事件的解决方法
May 07 Javascript
终于实现了!精彩的jquery弹幕效果
Jul 18 Javascript
Javascript之面向对象--方法
Dec 02 Javascript
Vue-router路由判断页面未登录跳转到登录页面的实例
Oct 26 Javascript
JavaScript中正则表达式使数字、中文或指定字符高亮显示
Oct 31 Javascript
webpack4+Vue搭建自己的Vue-cli项目过程分享
Aug 29 Javascript
Vue-Quill-Editor富文本编辑器的使用教程
Sep 21 Javascript
Vux+Axios拦截器增加loading的问题及实现方法
Nov 08 Javascript
JS轮播图的实现方法2
Aug 25 Javascript
JS组件Bootstrap实现弹出框和提示框效果代码
Dec 08 #Javascript
JS与jQ读取xml文件的方法
Dec 08 #Javascript
js实现select下拉框菜单
Dec 08 #Javascript
基于jQuery 实现bootstrapValidator下的全局验证
Dec 07 #Javascript
JavaScript的代码编写格式规范指南
Dec 07 #Javascript
JSON遍历方式实例总结
Dec 07 #Javascript
JS实现日期时间动态显示的方法
Dec 07 #Javascript
You might like
php绘图之加载外部图片的方法
2015/01/24 PHP
Javascript 判断Flash是否加载完成的代码
2010/04/12 Javascript
javascript event 事件解析
2011/01/31 Javascript
浅谈JavaScript编程语言的编码规范
2011/10/21 Javascript
javascript中的toFixed固定小数位数 简单实例分享
2013/07/12 Javascript
JQGrid的用法解析(列编辑,添加行,删除行)
2013/11/08 Javascript
Javascript 按位取反运算符 (~)
2014/02/04 Javascript
javascript中的括号()用法小结
2014/04/14 Javascript
js添加select下默认的option的value和text的方法
2014/10/19 Javascript
JavaScript常用小技巧小结
2014/12/29 Javascript
基于BootStrap Metronic开发框架经验小结【一】框架总览及菜单模块的处理
2016/05/12 Javascript
JS获取复选框的值,并传递到后台的实现方法
2016/05/30 Javascript
js本地图片预览实现代码
2016/10/09 Javascript
JS控制鼠标拒绝点击某一按钮的实例
2017/12/29 Javascript
微信小程序 网络通信实现详解
2019/07/23 Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
2019/12/09 Javascript
JS 逻辑判断不要只知道用 if-else 和 switch条件判断(小技巧)
2020/05/27 Javascript
Python实现利用163邮箱远程关电脑脚本
2018/02/22 Python
python如何派生内置不可变类型并修改实例化行为
2018/03/21 Python
Python利用openpyxl库遍历Sheet的实例
2018/05/03 Python
Python采集猫眼两万条数据 对《无名之辈》影评进行分析
2018/12/05 Python
解决PySide+Python子线程更新UI线程的问题
2019/01/11 Python
解决python 上传图片限制格式问题
2019/10/30 Python
手动安装python3.6的操作过程详解
2020/01/13 Python
使用Tensorflow将自己的数据分割成batch训练实例
2020/01/20 Python
python游戏开发的五个案例分享
2020/03/09 Python
python实现密码强度校验
2020/03/18 Python
解决Ubuntu18中的pycharm不能调用tensorflow-gpu的问题
2020/09/17 Python
4款Python 类型检查工具,你选择哪个呢?
2020/10/30 Python
CSS3 分类菜单效果
2019/05/27 HTML / CSS
Html5定位终极解决方案
2020/02/05 HTML / CSS
扩大国家免疫规划实施方案
2014/03/21 职场文书
拖欠货款起诉状
2015/05/20 职场文书
2019让人心动的商业计划书
2019/06/27 职场文书
浅谈redis五大数据结构和使用场景
2021/04/12 Redis
TypeScript实用技巧 Nominal Typing名义类型详解
2022/09/23 Javascript