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所必须要知道的一些
Mar 07 Javascript
《JavaScript高级程序设计》阅读笔记(三) ECMAScript中的引用类型
Feb 27 Javascript
Jquery和JS用外部变量获取Ajax返回的参数值的方法实例(超简单)
Jun 17 Javascript
jquery ready(fn)事件使用介绍
Aug 21 Javascript
js实现的倒计时按钮实例
Jun 24 Javascript
jQuery制作网页版选项卡
Jul 28 Javascript
利用JS提交表单的几种方法和验证(必看篇)
Sep 17 Javascript
完美解决js传递参数中加号和&amp;号自动改变的方法
Oct 11 Javascript
使用jsonp实现跨域获取数据实例讲解
Dec 25 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
Jan 13 Javascript
layui加载数据显示loading加载完成loading消失的实例代码
Sep 23 Javascript
Node.js API详解之 Error模块用法实例分析
May 14 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中文本数据翻页(留言本翻页)
2006/10/09 PHP
一些PHP写的小东西
2006/12/06 PHP
抓取YAHOO股票报价的类
2009/05/15 PHP
PHP里的中文变量说明
2011/07/23 PHP
php中获得视频时间总长度的另一种方法
2011/09/15 PHP
php实现比较两个文件夹异同的方法
2015/06/18 PHP
php微信开发之上传临时素材
2016/06/24 PHP
CI(CodeIgniter)框架视图中加载视图的方法
2017/03/24 PHP
jquery插件jbox使用iframe关闭问题
2009/02/09 Javascript
javascript Array.sort() 跨浏览器下需要考虑的问题
2009/12/07 Javascript
JavaScript中reduce()方法的使用详解
2015/06/09 Javascript
js console.log打印对像与数组用法详解
2016/01/21 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
2016/07/11 Javascript
require.js 加载 vue组件 r.js 合并压缩的实例
2016/10/14 Javascript
多种方式实现js图片预览
2016/12/12 Javascript
jQuery实现遍历复选框的方法示例
2017/03/06 Javascript
vue中的非父子间的通讯问题简单的实例代码
2017/07/19 Javascript
Vue.js用法详解
2017/11/13 Javascript
react在安卓中输入框被手机键盘遮挡问题的解决方法
2018/09/03 Javascript
JS面试题大坑之隐式类型转换实例代码
2018/10/14 Javascript
封装微信小程序http拦截器过程解析
2019/08/13 Javascript
JavaScript命令模式原理与用法实例详解
2020/03/10 Javascript
基于openlayers实现角度测量功能
2020/09/28 Javascript
vue 判断两个时间插件结束时间必选大于开始时间的代码
2020/11/04 Javascript
JavaScript实现点击切换功能
2021/01/27 Javascript
[47:21]Liquid vs TNC Supermajor 胜者组 BO3 第一场 6.4
2018/06/05 DOTA
Python的socket模块源码中的一些实现要点分析
2016/06/06 Python
Python 项目转化为so文件实例
2019/12/23 Python
python实现Oracle查询分组的方法示例
2020/04/30 Python
python相对企业语言优势在哪
2020/06/12 Python
利用HTML5的新特点实现图片文件异步上传
2014/05/29 HTML / CSS
移动通信行业实习自我鉴定
2013/09/28 职场文书
大学生万能检讨书范例
2014/10/04 职场文书
学习十八大的感悟
2015/08/11 职场文书
PHP新手指南
2021/04/01 PHP
JavaScript中的LHS和RHS分析详情
2022/04/06 Javascript