点击查看AngularJS系列目录
转载请注明出处:http://www.cnblogs.com/leosx/


什么是AngularJS的模块

我们所说的模块,是你的AngularJS应用程序的一个组成部分,它可以是一个Controller,也可以是一个Service服务,也可以是一个过滤器(Filter),也可以是一个directive(指令)等等…都是属于一个模块!

大多数的应用程序都是有一个自己的函数入口方法Main ,用它来进行初始化,以及加载装配各个模块,然后这些模块的组合,构成了你的应用程序,对吧?

但是,but, AngularJS应用程序却不是这样的哦,它没有main 方法,没有函数入口。代替之的是在模块中指定声明这个模块在AngularJS应用程序中该如何去加载,启动。这种方法有以下几个优点:

1) 使用声明的方式,让人更加容易理解。

2) 你可以更加容易的让你的代码进行重用。

3) 模块的加载顺序就更加容易控制了。因为这些模块是延迟执行的。

4) 对于进行单元测试就变得更加的方便了。更加可靠,你只需要载入这个模块就可以进行测试了。

5) 端对端的测试中,你可以使用模块去重写配置。

还是看看代码最重要,直接上代码:

<div ng-app="myApp">
<div>
{{ 'World' | greet }}
</div>
</div>
<script src="https://code.angularjs.org/1.3.0/angular.min.js"></script>
<script type="text/javascript">
(function(){
// declare a module
var myAppModule = angular.module('myApp', []); // configure the module.
// in this example we will create a greeting filter
myAppModule.filter('greet', function() {
return function(name) {
return 'Hello, ' + name + '!';
};
});
})();
</script>

单元测试的代码:

it('should add Hello to the name', function() {
expect(element(by.binding("'World' | greet")).getText()).toEqual('Hello, World!');
});

效果图:

有几个事情需要注意一下的:

1. 关于模块的API,点击这里

2. <div ng-app=”myApp”>引用了myApp 模块。 这既是告诉启动器,你使用了这个名为myApp的模块,当AngularJS启动的时候,它就会去加载力的这个模块。

3. 在 angular.module(‘myApp’, [] )中,有个空的数组,这个数组是myApp模块说依赖的模块的列表.

推存设置

上面的例子都是非常简单的。它不是大型应用。我们建议你将你的AngularJS应用程序碎片化,也就是让你的应用程序变成多个模块的组合,例如:

1.不同的业务,为一个模块。

2.一个模块中,包含很多可以重用的组件(特别是指令和过滤器,以后也可以使用的)

3.一个应用程序级别的模块,它依赖于上级的模块,并且它还包含有所有的初始化代码。。。

在Google上,有一个关于如何编写大型应用程序的文档,你可以点击这里查看。

当然咯!  上面的都是建议,你可以根据你的需求,进行量身定做。比如:

<div ng-app="xmpl">
<div ng-controller="XmplController">
{{ greeting }}
</div>
</div>
<script src="https://code.angularjs.org/1.3.0/angular.min.js"></script>
<script type="text/javascript">
(function(){
angular.module('xmpl.service', []) .value('greeter', {
salutation: 'Hello',
localize: function(localization) {
this.salutation = localization.salutation;
},
greet: function(name) {
return this.salutation + ' ' + name + '!';
}
}) .value('user', {
load: function(name) {
this.name = name;
}
}); angular.module('xmpl.directive', []); angular.module('xmpl.filter', []); angular.module('xmpl', ['xmpl.service', 'xmpl.directive', 'xmpl.filter']) .run(function(greeter, user) {
// This is effectively part of the main method initialization code
greeter.localize({
salutation: 'Bonjour'
});
user.load('World');
}) .controller('XmplController', function($scope, greeter, user){
$scope.greeting = greeter.greet(user.name);
});
})();
</script>

效果图:

模块的加载和依赖

一个模块,其实是一个在应用程序的引导程序中运行的,一个配置的集合和运行块的集合。

1. 配置模块,它可以在provider提供者中进行注册,还可以再配置应用阶段进行执行。只有provider和常量才能够被注入到配置块中去。这样做是为了防止在配置块没有配置完成之前,意外的实例化了服务,这是不被允许的。

2. 运行(run)块, 是在注入器被创建出来之后和被用于应用程序之后,进行执行的。只有实例对象和常量能够被注入到 运行(run )块当中。这样做的目的是为了防止在应用程序运行期间,增加,修改了系统配置。

来看看例子:

angular.module('myModule', []).
config(function(injectables) { // provider-injector
// This is an example of config block.
// You can have as many of these as you want.
// You can only inject Providers (not instances)
// into config blocks.
}).
run(function(injectables) { // instance-injector
// This is an example of a run block.
// You can have as many of these as you want.
// You can only inject instances (not Providers)
// into run blocks
});

配置块

其实在模块上有一些非常方便的方法,它们就相当于是一个 config 配置块,看例子:

angular.module('myModule', []).
value('a', 123).
factory('a', function() { return 123; }).
directive('directiveName', ...).
filter('filterName', ...); // is same as angular.module('myModule', []).
config(function($provide, $compileProvider, $filterProvider) {
$provide.value('a', 123);
$provide.factory('a', function() { return 123; });
$compileProvider.directive('directiveName', ...);
$filterProvider.register('filterName', ...);
});

当AngularJS在进行引导启动你的应用程序的时候,它会首先定义所有的常量。然后再在配置块中使用同一个 常量列表 去注册它们。

运行块(Run)

Run,我们这里叫运行块,它是最接近Main入口函数的一个方法。运行块(run) 是建立在AngularJS应用程序之上的。它会在所有的服务配置完毕,注入器被创建完毕之后执行。。 一个运行块(run block) 通常会包含着单元测试,正因如此,应该把他声明在一个独立的模块(module)当中,这样,就可以把单元测试给独立开来了。

依赖关系

一个模块,它知道所有它所依赖的其它模块,也就是说在它加载起来前,需要将它所依赖的其它所有模块给加载起来。换句换说,对于需要配置块的模块来说,配置块一定是在需要它的模块初始化之前就被初始化完毕了。 同样的,运行块(run block)也是这样的,一个模块,会且仅会被加载一次,无论有多少个模块引用了它,它都只会被加载一次的。

异步加载(Asynchronous Loading)

Modules are a way of managing $injector configuration, and have nothing to do with loading of scripts into a VM. There are existing projects which deal with script loading, which may be used with Angular. Because modules do nothing at load time they can be loaded into the VM in any order and thus script loaders can take advantage of this property and parallelize the loading process.(这句话实在翻译不了,英文太烂,有看到并且英文好的哥们儿,望帮忙翻译下)

创建和检索

在使用 angular.module(‘myModule’, [] )的时候得注意,它会创建一个叫做 myModule的模块,并且会覆盖掉所有之前叫做 myModule 的模块。  我们使用 angular.module(‘myModule’) 就可以去查找,检索我们已经创建的模块。来个例子:

var myModule = angular.module('myModule', []);

// add some directives and services
myModule.service('myService', ...);
myModule.directive('myDirective', ...); // overwrites both myService and myDirective by creating a new module
var myModule = angular.module('myModule', []); // throws an error because myOtherModule has yet to be defined
var myModule = angular.module('myOtherModule');

单元测试

单元测试是一个很好的去初始化你的应用模块,并且调用它的一个小的应用。  有结构的模块对于单元测试时非常有用的,可以很好的找到关注重点。

一个模块只能在注入器(injector) 中被加载一次,且仅有一次。通常,一个Angular 应用程序只有一个 注入器(injector) 而且所有模块只会被加载一次。但是每个单元测试都会有自己的注入器(injector) ,而且模块可以被加载多次。 在我们的所有例子中,都遵循了模块定义的这个规则:

angular.module('greetMod', []).

factory('alert', function($window) {
return function(text) {
$window.alert(text);
}
}). value('salutation', 'Hello'). factory('greet', function(alert, salutation) {
return function(name) {
alert(salutation + ' ' + name + '!');
}
});

我们来写一些单元测试,来看看在单元测试当中如何重写配置

describe('myApp', function() {
// load application module (`greetMod`) then load a special
// test module which overrides `$window` with a mock version,
// so that calling `window.alert()` will not block the test
// runner with a real alert box.
beforeEach(module('greetMod', function($provide) {
$provide.value('$window', {
alert: jasmine.createSpy('alert')
});
})); // inject() will create the injector and inject the `greet` and
// `$window` into the tests.
it('should alert on $window', inject(function(greet, $window) {
greet('World');
expect($window.alert).toHaveBeenCalledWith('Hello World!');
})); // this is another way of overriding configuration in the
// tests using inline `module` and `inject` methods.
it('should alert using the alert service', function() {
var alertSpy = jasmine.createSpy('alert');
module(function($provide) {
$provide.value('alert', alertSpy);
});
inject(function(greet) {
greet('World');
expect(alertSpy).toHaveBeenCalledWith('Hello World!');
});
});
});

AngularJS -- Module (模块)的更多相关文章

  1. AngularJS多模块开发

    angularJS中的多模块开发是指多个module模块开发,步骤为: 1. 确定主模块    var app=angular.module('myApp',[]); 2. 其他的子模块添加到主模块后 ...

  2. 03、AngularJs的模块与控制器

    大部分的应用程序都有一个主方法(main)来组织,实例化,启动应用程序.而AngularJs应用是没有主方法的,它是通过模块来声明应用应该如何启动的.同时,模块允许声明来描述应用中依赖关系,以及如何进 ...

  3. Angularjs 异步模块加载项目模板

    ng-lazy-module-seed(Angularjs 异步模块加载项目模板) 相信做过SPA项目的朋友都遇到过这个问题:页面初始化时需要加载文件太大或太多了,许多文件加载后很可能不会运行到,这是 ...

  4. AngularJS-01.AngularJS,Module,Controller,scope

    1.AngularJS 一个构建动态Web应用程序的结构化框架. 基于JavaScript的MVC框架.(  MVC ---- Model(模型).View(视图).Controller(控制器) ) ...

  5. 利用Module模块把构建的神经网络跑起来

    训练一个神经网络往往只需要简单的几步: 准备训练数据 初始化模型的参数 模型向往计算与向后计算 更新模型参数 设置相关的checkpoint 如果上述的每个步骤都需要我们写Python的代码去一步步实 ...

  6. AngularJs angular.Module模块接口配置

    angular.Module Angular模块配置接口. 方法: provider(name,providerType); name:服务名称. providerType:创建一个服务的实例的构造函 ...

  7. AngularJs(七) 模块的创建

    module 目前我选编写的都是在AngularJs-1.5版本,如有疑问可以联系我. 理解模块的生命周期. config 和 run 方法是模块调用时加载的方法.那么module的执行顺序是怎么样呢 ...

  8. Angularjs Module类的介绍及模块化依赖

    后面的学习我们会遵循一个控制器管理一个视图,一个路由对应一个视图的单一原则,所以再不会将controller控制器代码直接写到 index.html 中. 我们会应用到angular.js中强大的模块 ...

  9. AngularJS 常用模块书写建议

    本文是依据 Angular Style Guide 对 Angular 常用模块书写建议的翻译和总结,仅供参考. IIFE 使用 立即执行函数表达式(Immediately Invoked Funct ...

随机推荐

  1. app端性能测试笔记

     IOS不清楚,我就说说android平台吧 1.按不同维度  APP级性能.代码级性能      app这一级   GT啊  emmage都可以检测 2.代码级性能的话  有可以分几块 函数性能UI ...

  2. 延迟实例化 Lazy<T>

    之前写的设计模式 单例模式中,推荐了使用Lazy<T>来达到线程安全和减少系统资源消耗的作用. 作用及优点: 创建某一个对象需要很大的消耗,而这个对象在运行过程中又不一定用到,为了避免每次 ...

  3. Chome——扩展程序,获取更多扩展程序报错

    修改/替换hosts文件 地址:c:/windows/system32/drivers/etc hosts:可从网上搜索下载或网盘下载(链接: http://pan.baidu.com/s/1bpu6 ...

  4. LVS之DR模式实战及高可用性

    author:JevonWei 版权声明:原创作品 LVS-DR实现同网段调度web模式 拓扑环境 网络环境 RS1 RIP 192.168.198.138/24 VIP 192.168.198.10 ...

  5. webservice中jaxws:server 和jaxws:endpoint的区别

    今天在学习使用spring+cxf发布webservice时遇到个问题,我原来是用 <jaxws:endpoint id="helloWorld" implementor=& ...

  6. Springmvc_validation 效验器

    springmvc-validation效验器的使用介绍 对于任何一个应用来说,都会做数据的有效性效验,但是只在前端做并不是很安全,考虑到安全性這个时候会要求我们在服务端也对数据进行有效验证,spri ...

  7. 汇编指令-bic(位清除)、orr(位或)(3)

    1. bic  (Bit Clear)位清除指令bic指令的格式为:bic{条件}{S}  Rd,Rn,operand bic指令将Rn 的值与操作数operand2 的反码按位逻辑"与&q ...

  8. python爬虫-抓取acg12动漫壁纸排行设置为桌面壁纸

    ACG-wallpaper 初学python,之前想抓取P站的一些图片来着,然后发现acg12这里有专门的壁纸榜单,就写了个抓取壁纸作为mac桌面壁纸玩玩. 功能:抓取acg12壁纸榜单的动漫壁纸,并 ...

  9. Sqlite数据库添加数据以及查询数据方法

    只是两个添加查询方法而已,怕时间长不用忘了

  10. NOPI读xls文件写到txt中(NPOI系列二)

    private void button2_Click(object sender, EventArgs e) { StringBuilder sb = new StringBuilder(); //找 ...