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 相关文章推荐
jquery multiSelect 多选下拉框
Jul 09 Javascript
图片img的src不变让浏览器重新加载实现方法
Mar 29 Javascript
javaScript实现浮点数转十六进制字符
Oct 29 Javascript
JS模式之简单的订阅者和发布者模式完整实例
Jun 30 Javascript
javascript图片预加载完整实例
Dec 10 Javascript
阿里巴巴技术文章分享 Javascript继承机制的实现
Jan 14 Javascript
浅析使用BootStrap TreeView插件实现灵活配置快递模板
Nov 28 Javascript
JS使用正则实现去掉字符串左右空格的方法
Dec 27 Javascript
canvas学习之API整理笔记(一)
Dec 29 Javascript
vue-cli构建项目使用 less的方法
Oct 04 Javascript
Vue通过WebSocket建立长连接的实现代码
Nov 05 Javascript
浅谈Vue static 静态资源路径 和 style问题
Nov 07 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调用MsSQL Server 2012存储过程获取多结果集(包含output参数)的详解
2013/07/03 PHP
PHP实现事件机制实例分析
2015/06/26 PHP
CI配置多数据库访问的方法
2016/03/28 PHP
基于thinkphp6.0的success、error实现方法
2019/11/05 PHP
JS 统计时间
2021/03/09 Javascript
jquery实现图片灯箱明暗的遮罩效果
2013/11/15 Javascript
JS实现很酷的水波文字特效实例
2015/02/26 Javascript
Js实现无刷新删除内容
2015/04/29 Javascript
轻松学习jQuery插件EasyUI EasyUI实现树形网络基本操作(2)
2015/11/30 Javascript
JavaScript动态设置div的样式的方法
2015/12/26 Javascript
JS获取屏幕高度的简单实现代码
2016/05/24 Javascript
原生js代码实现图片放大境效果
2016/10/30 Javascript
Base64(二进制)图片编码解析及在各种浏览器的兼容性处理
2017/02/09 Javascript
jQuery实现文档树效果
2017/02/20 Javascript
swiper在angularjs中使用循环轮播失效的解决方法
2018/09/27 Javascript
iview通过Dropdown(下拉菜单)实现的右键菜单
2018/10/26 Javascript
浅谈Vue.js 关于页面加载完成后执行一个方法的问题
2019/04/01 Javascript
Vue extend的基本用法(实例详解)
2019/12/09 Javascript
jQuery实现异步上传一个或多个文件
2020/08/17 jQuery
python爬虫爬取淘宝商品信息
2018/02/23 Python
Python 将Matrix、Dict保存到文件的方法
2018/10/30 Python
python之PyQt按钮右键菜单功能的实现代码
2019/08/17 Python
python中对_init_的理解及实例解析
2019/10/11 Python
解决python gdal投影坐标系转换的问题
2020/01/17 Python
如何在Win10系统使用Python3连接Hive
2020/10/15 Python
美国知名女性服饰品牌:New York & Company
2017/03/23 全球购物
Vans荷兰官方网站:美国南加州的原创极限运动潮牌
2018/01/23 全球购物
巴西儿童时尚购物网站:Dinda
2019/08/14 全球购物
Shopee菲律宾:在线购买和出售
2019/11/25 全球购物
生物专业个人自荐信范文
2013/11/29 职场文书
《蚕姑娘》教学反思
2014/04/15 职场文书
数字化校园建设方案
2014/05/03 职场文书
企业法人授权委托书
2014/09/25 职场文书
大学生违纪检讨书300字
2014/10/25 职场文书
学校师德师风整改措施
2014/10/27 职场文书
2014年学校法制宣传日活动总结
2014/11/01 职场文书