Angular JS的模块依赖
AngularJS是纯客户端技术,完全用Javascript编写的。它使用的是网页开发的常规技术(HTML,CSS,Javascript),目的是让网页应用开发更快更容易。
AngularJS简化应用开发的一个重要方法是,将一个些通用的低级开发操作包装起来提供给开发者。AngularJS会自动处理好这些低级操作。它们包括:
1.DOM操作
2.设置事件的监听
3.输入验证,因为AngularJS会处理大部分这些操作,所以开发者就能更多的专注在应用的业务逻辑上,更少地编写那些重复性的、易错的、低级的代码。
在AngularJS简化开发的同时,它也为客户端带来了一些精巧的技术,它们包括:
1.数据、业务逻辑、视图的分离
2.数据和视图的自动绑定
3.通用服务
4.依赖注入(主要用于聚合服务)
5.可扩展的HTML编译器(完全由JavaScript编写)
6.易于测试
7.客户端对这些技术的需求其实已经存在很久了。
同时,你还可以用AngularJS来开发单页或者多页的应用,不过其主要还是用来开发单页的。 AngularJS支持浏览器的历史操作,向前,向后按钮,单页应用中的收藏操作。
接下来,我们来详细讲解angularJS的模块。
大部分应用都有一个主方法用来实例化、组织、启动应用。AngularJS应用没有主方法,而是使用模块来声明应用应该如何启动。这种方式有以下几个优点:
1.启动过程是声明式的,所以更容易懂。
2.在单元测试是不需要加载全部模块的,因此这种方式有助于写单元测试。
3.可以在特定情况的测试中增加额外的模块,这些模块能更改配置,能帮助进行端对端的测试。
4.第三方代码可以打包成可重用的模块。
5.模块可以以任何先后或者并行的顺序加载(因为模块的执行本身是延迟的)。
举个例子:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
 | 
<!doctype html><html ng-app="myApp"> <head>  <script>      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> </head> <body>  <div>   {{ 'World' | greet }}  </div> </body></html> | 
上面的例子,我们是通过在<html ng-app="myApp">中进行指定,来实现使用myApp这个模块启动应用的。
以上这个例子写法很简单,但是不适合用同样的写法来写大型应用。我们推荐是将你的应用拆分成以下几个模块:
1.一个服务模块,用来做服务的声明。
2.一个指令模块,用来做指令的声明。
3.一个过滤器模块,用来做过滤器声明。
4.一个依赖以上模块的应用级模块,它包含初始化代码。
举个例子:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
 | 
<!doctype html><html ng-app="xmpl"> <head>  <script src="script.js"></script> </head> <body>  <div ng-controller="XmplController">   {{ greeting }}!  </div> </body></html>[/code]script.js:[code]angular.module('xmpl.service', []).   //服务模块 value('greeter', {    //自定义greeter对象  salutation: 'Hello',  localize: function(localization) {    this.salutation = localization.salutation;  },  greet: function(name) {    return this.salutation + ' ' + name + '!';  } }). value('user', {   //自定义user对象  load: function(name) {    this.name = name;  } });angular.module('xmpl.directive', []);  //指令模块angular.module('xmpl.filter', []);   //过滤器模块angular.module('xmpl', ['xmpl.service', 'xmpl.directive', 'xmpl.filter']).  //模块xmpl依赖于数组中的模块 run(function(greeter, user) {  // 初始化代码,应用启动时,会自动执行  greeter.localize({    salutation: 'Bonjour'  });  user.load('World'); })// A Controller for your appvar XmplController = function($scope, greeter, user) {   $scope.greeting = greeter.greet(user.name);} | 
这样拆分的原因是,在你的测试中常常需要忽略掉初始化代码,因为这些代码比较难测试。通过把它拆分出来就能在测试中方便地忽视掉它。通过只加载和当前测试相关的模块,也能使测试更专一。以上只是一个建议,你可以放心根据你的具体情况来调整。
一个模块就是一系列配置和代码块的集合,它们是在启动阶段就附加到应用上的。一个最简单的模块由两类代码块集合组成的:
配置代码块 - 在注入提供者注入和配置阶段执行。只有注入提供者和常量可以被注入到配置块中。这是为了防止服务在被配置好之前就被提前初始化。
运行代码块 - 在注入器被创建后执行,被用来启动应用的。只有实例和常量能被注入到运行块中。这是为了防止在运行后还出现对系统的配置。
代码实现:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
 | 
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 the 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 the run blocks  }); | 
模块还有一些配置的简便方法,使用它们的效果等同于使用代码块。举个例子:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
 | 
angular.module('myModule', []). value('a', 123). factory('a', function() { return 123; }). directive('directiveName', ...). filter('filterName', ...);// is same asangular.module('myModule', []). config(function($provide, $compileProvider, $filterProvider) {  $provide.value('a', 123)  $provide.factory('a', function() { return 123; })  $compileProvider.directive('directiveName', ...).  $filterProvider.register('filterName', ...); }); | 
配置块会按照$provide, $compileProvider, $filterProvider,注册的顺序,依次被应用。唯一的例外是对常量的定义,它们应该始终放在配置块的开始处。
运行块是AngularJS中最像主方法的东西。一个运行块就是一段用来启动应用的代码。它在所有服务都被配置和所有的注入器都被创建后执行。运行块通常包含了一些难以测试的代码,所以它们应该写在单独的模块里,这样在单元测试时就可以忽略它们了。
模块可以把其他模块列为它的依赖。“依赖某个模块”意味着需要把这个被依赖的模块在本块模块之前被加载。换句话说被依赖模块的配置块会在本模块配置块前被执行。运行块也是一样。任何一个模块都只能被加载一次,即使它被多个模块依赖。
模块是一种用来管理$injector配置的方法,和脚本的加载没有关系。现在网上已有很多控制模块加载的库,它们可以和AngularJS配合使用。因为在加载期间模块不做任何事情,所以它们可以以任意顺序或者并行方式加载
Angular JS的模块依赖的更多相关文章
- Angular JS中的依赖注入
		
依赖注入DI angularjs中与DI相关有angular.module().angular.injector(). $injector.$provide. DI 容器3要素:服务的注册.依赖关系的 ...
 - angular js 自定义添加依赖
		
代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
 - angular.js添加自定义服务依赖项方法
		
<!DOCTYPE html> <html lang="en" ng-app="myapp"> <head> <met ...
 - angular js 上传插件  ng-file-upload 使用时注意事项
		
项目框架为angular js,需要用到文件上传,百度之后先选择了angular-file-upload,githuab上API文档很全,想要具体了解,可以仔细研究一下.在这里简单回顾一下自己使用的插 ...
 - angular.js的依赖注入解析
		
本教程使用AngularJS版本:1.5.3 angularjs GitHub: https://github.com/angular/angular.js/ Angula ...
 - Angular JS - 5 - Angular JS 模块和控制器
		
1.引入 1.5版本的angularjs,直接打印angular对象: --> <!DOCTYPE html> <html> <head lang="en ...
 - Angular.JS + Require.JS + angular-async-loader 来实现异步加载 angular 模块
		
传统的 angular 应用不支持异步加载模块,必须在 module 启动的时候,所有模块必须预加载进来. 通过使用 angular-async-loader 库,我们可以使用 requirejs 等 ...
 - MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录
		
注:文章内容都是摘录性文字,自己阅读的一些笔记,方便日后查看. MVC MVC(Model-View-Controller),M 是指业务模型,V 是指用户界面,C 则是控制器,使用 MVC 的目的是 ...
 - Angular JS 学习之路由
		
1.AngularJS路由允许我们通过不同的URL访问不同的内容:通过AngularJS可以实现多视图的单页WEB访问(SPA) 2.通常我们的URL形式为http://runoob.com/firs ...
 
随机推荐
- Android微信智能心跳方案 (转)
			
原创 2015-08-17 phoenix WeMobileDev 前言:在13年11月中旬时,因为基础组件组人手紧张,Leo安排我和春哥去广州轮岗支援.刚到广州的时候,Ray让我和春哥对Line和W ...
 - Linux内核创建一个新进程
			
张雨梅 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000 创建新进程 如果同一个程序被多 ...
 - vc6.0如何显示行号以及出现版本不兼容问题
			
有时编译时,提示某某行有错,但是要定位到某一行的话,如果在编辑页面能够将行号显示出来,查找也就更方便了,下面我来介绍一下让VC6.0显示行号的方法. 工具/原料 VC6.0.显示行号的插件 方 ...
 - Freemaker 自定义函数
			
定义格式如下: <#function name param1 param2 ... paramN> ... <#return returnValue> ... </#fu ...
 - MyEclipse 不能编译Java类到Classes文件夹
			
设置Java Build Path -> Resource -> Default output folder 到一个新的文件夹XXXproject/WebContent/WEB-INF/c ...
 - zoj 1788 Quad Trees
			
zoj 1788 先输入初始化MAP ,然后要根据MAP 建立一个四分树,自下而上建立,先建立完整的一棵树,然后根据四个相邻的格 值相同则进行合并,(这又是递归的伟大),逐次向上递归 四分树建立完后, ...
 - android 中调用接口发送短信
			
android中可以通过两种方式发送短信 第一:调用系统短信接口直接发送短信:主要代码如下: //直接调用短信接口发短信 SmsManager smsManager = SmsManager.getD ...
 - 使用简单NGUI加载进度条
			
1.在Panel上添加Slider,GNUI--Open--Widget Wizard--Slider,设置Empty和Full 2.在Panel上添加Label,GNUI--Open--Widget ...
 - 拆分SharePoint 2013 中CreatedModifiedInfo 的时间
			
最近在自定义DisForm.aspx页面时 发现 创建时间信息无法进行拆分,人事MM只想要修改时间,去掉创建人,创建时间和修改人. 于是我的重新研究下在SPD里面如何去拆分这个时间. 在详情页面上找到 ...
 - C++ 多态、虚函数机制以及虚函数表
			
1.非virtual函数,调用规则取决于对象的显式类型.例如 A* a = new B(); a->display(); 调用的就是A类中定义的display().和对象本体是B无关系. 2. ...