AngularJs学习笔记--Modules

原版地址:http://code.angularjs.org/1.0.2/docs/guide/module

 

一、什么是Module

  很多应用都有一个用于初始化、加载(wires是这个意思吗?)和启动应用的main方法。angular应用不需要main方法,作为替代,module提供有指定目的的声明式,描述应用如何启动。这样做有几项优点:

  • 这过程是声明描述的,更加容易读懂。
  • 在单元测试中,不需要加载所有module,这对写单元测试很有帮助。
  • 额外的module可以被加载到情景测试中,可以覆盖一些设置,帮助进行应用的端对端测试(end-to-end test)。
  • 第三方代码可以作为可复用的module打包到angular中。
  • module可以通过任意顺序或并行加载(取决于模块执行的延迟性,due to delayed nature of module execution)。

 

二、The Basics(基础)

  我们很迫切想知道如何让Hello World module能够工作。下面有几个关键的事情要注意:

  • module APIhttp://code.angularjs.org/1.0.2/docs/api/angular.Module
  • 注意的提及的在<html ng-app=”myApp”>中的myApp module,它让启动器启动我们定义的myApp module
<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="myApp">
<head><meta charset="UTF-8"><title>basics</title><style type="text/css">.ng-cloak {display: none;}</style>
</head>
<body>
<div class="ng-cloak">{{'Kitty' | greet}}
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">var simpleModule = angular.module("myApp", []);simpleModule.filter("greet", function () {return function(name) {return "Hello " + name + " !";}});
</script>
</body>
</html>

 

三、(Recommended Setup)推荐设置

  虽然上面的例子很简单,它不属于大规模的应用。我们建议将自己的应用按照如下建议,拆分为多个module

  • service module,用于声明service
  • directive module,用于声明directive
  • filter module,用于声明filter
  • 应用级别的module,依赖上述的module,并且包含初始化的代码。

  这样划分的理由是,当我们在测试的时候,往往需要忽略那些让测试变得困难的初始化代码。通过将代码分成独立的module,在测试中就可以很容易地忽略那些代码。这样,我们就可以更加专注在加载相应的module进行测试。

  上面的只是一个建议,可以随意地按照自己的需求制定。

 

四、Module Loading & Dependencies(模块加载和依赖)

  module是配置(configuration)的集合,执行在启动应用的进程中应用的块(blocks)。在它的最简单的形式中,由两类block组成:

  1.配置块(configuration blocks):在provider注册和配置的过程中执行的。只有providerconstant(常量?)可以被注入(injected)到configuration blocks中。这是为了避免出现在service配置完毕之前service就被执行的意外。

  2.运行块(run blocks):在injector创建完成后执行,用于启动应用。只有实例(instances)和常量(constants)可以被注入到run block中。这是为了避免进一步的系统配置在程序运行的过程中执行。

angular.module('myModule', []).config(function(injectables) { // provider-injector// 这里是config block的一个例子// 我们可以根据需要,弄N个这样的东东// 我们可以在这里注入Providers (不是实例,not instances)到config block里面
}).run(function(injectables) { // instance-injector// 这里是一个run block的例子// 我们可以根据需要,弄N个这样的东东// 我们只能注入实例(instances )(不是Providers)到run block里面

});

 

  a) Configuration Blocks(配置块)

  有一个方便的方法在module中,它相当于config block。例如:

angular.module('myModule', []).value('a', 123).factory('a', function() { return 123; }).directive('directiveName', ...).filter('filterName', ...);// 等同于

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

  configuration blocks被应用的顺序,与它们的注册的顺序一致。对于常量定义来说,是一种额外的情况,即放置在configuration blocks开头的常量定义。

 

  b) Run Blocks(应用块)

  run block是在angular中最接近main方法的东东。run block是必须执行,用于启动应用的代码。它将会在所有service配置、injector创建完毕后执行。run block通常包含那些比较难以进行单元测试的代码,就是因为这个原因,这些代码应该定义在一个独立的module中,让这些代码可以在单元测试中被忽略。

 

  c) Dependencies(依赖)

  一个module可以列出它所依赖的其他module。依赖一个module,意味着被请求(required)的module(被依赖的)必须在进行请求(requiringmodule(需要依赖其他modulemodule,请求方)加载之前加载完成。换一种说法,被请求的moduleconfiguration block会在请求的moduleconfiguration block执行前执行(before the configuration blocks or the requiring module,这里的or怎么解释呢?)。对于run block也是这个道理。每一个module只能够被加载一次,即使有多个其他module需要(require)它。

 

  d) Asynchronous Loading(异步加载)

  module是管理$injector配置的方法之一,不用对加载脚本到VM做任何事情。现在已经有现成的项目专门用于处理脚本加载,也可以用到angular中。因为module在加载的过程中不做任何事情,它们可以按照任意的顺序被加载到VM中。脚本加载器可以利用这个特性,进行并行加载。

 

五、Unit Testing(单元测试)

  在单元测试的最简单的形式中,其中一个是在测试中实例化一个应用的子集,然后运行它们。重要的是,我们需要意识到对于每一个injector,每一个module只会被加载一次。通常一个应用只会有一个injector。但在测试中,每一个测试用例都有它的injector,这意味着在每一个VM中,module会被多次加载。正确地构建module,将对单元测试有帮助,正如下面的例子:

  在这个例子中,我们准备假设定义如下的module

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() {// 加载应用响应的module,然后加载指定的将$window重写为mock版本的测试module,// 这样做,当进行window.alert()时,测试器就不会因被真正的alert窗口阻挡而停止//这里是一个在测试中覆盖配置信息的例子beforeEach(module('greetMod', function($provide) {//这里看来是要将真正的$window替换为以下的东东$provide.value('$window', {alert: jasmine.createSpy('alert')});}));// inject()会创建一个injector,并且注入greet和$window到测试中。// 测试不需要关心如何写应用,只需要关注如何测试应用。it('should alert on $window', inject(function(greet, $window) {greet('World');expect($window.alert).toHaveBeenCalledWith('Hello World!');}));// 这里是在测试中通过行内module和inject方法来覆盖配置的方法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!');});});
});

 

By Lcllao

转载于:https://www.cnblogs.com/lcllao/archive/2012/09/22/2698208.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/474936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电商用户行为分析与挖掘(MYSQL数据分析+SPSS构建RFM模型)

前言 毫不夸张的说在中国除了婴幼儿及七八十以上的老年人&#xff0c;都有过网购经历。电商公司就如雨后春笋般迅速发展。了解用户的网购行为&#xff0c;有助于商家定品类&#xff0c;定营销方案等。利用数据分析与挖掘&#xff0c;争取做到比顾客自己还了解TA自己。 文章目录…

LeetCode MySQL 1113. 报告的记录

文章目录1. 题目2. 解题1. 题目 动作表&#xff1a;Actions ------------------------ | Column Name | Type | ------------------------ | user_id | int | | post_id | int | | action_date | date | | action | enum | | extra…

展开BOM

Select LEVEL, ixkit, ixkitl, ixmmcu, ixitm, ixlitm, ixcmcu From jdedata900.f3002 START WITH ixkit 60661CONNECT BY PRIOR ixitm ixkit; 转载于:https://www.cnblogs.com/AlterMe/archive/2012/09/24/2699424.html

淘宝用户行为分析

前言 现在越来越多的线下转型到了线上经营&#xff0c;线下体验店线上购物将成为日后消费的大趋势。分析用户行为&#xff0c;走好转型之路&#xff0c;掌握先机快人一步。 文章目录前言一、背景Ⅰ 数据来源Ⅱ 数据背景Ⅲ 分析目的二、探索性分析Ⅰ 导入数据Ⅱ 数据处理1、缺失…

LeetCode 第 198 场周赛(434/5778,前7.51%)

文章目录1. 比赛结果2. 题目1. LeetCode 5464. 换酒问题 easy2. LeetCode 5465. 子树中标签相同的节点数 medium3. LeetCode 5466. 最多的不重叠子字符串 medium4. LeetCode 5467. 找到最接近目标值的函数值 hard1. 比赛结果 第二题图的边给的不一定按顺序的&#xff0c;我按有…

unzipped list

今天实现了一个unzipped操作&#xff0c;比如 (list (list 1 2) (list 3 4) (list 5 6)) -> (list (list 1 3 5) (list 2 4 6)) 这个实现起来没有什么难度&#xff0c;但是scheme中的表操作折腾了好久才没错。 (define (unzipped l) (if (null? l) (list () ()) (li…

关于数据运营的一点小思考

随着互联网行业的快速发展&#xff0c;其所带来的行业红利和流量红利基本上告别野蛮生长阶段&#xff0c;现代人越来越依赖互联网&#xff0c;看似市场大&#xff0c;但用户选择多&#xff0c;互联网产品淘汰得比刚开始更快。野蛮生长虽然发展快&#xff0c;但是伴随的弊端也随…

BZOJ 2197 [Usaco2011 Mar]Tree Decoration

BZOJ_2197 如果子树中有某个节点不符合要求&#xff0c;即便根再怎么符合要求都是没有任何意义的&#xff0c;因此要优先安排好子树中节点使其符合要求&#xff0c;再考虑根节点。对于任何一棵子树来讲&#xff0c;如果所有孩子选择的点的总和仍然不足根的C值的话&#xff0c;那…

清华镜像源安装 NGboost XGboost Catboost

清华镜像源安装 NGboost XGboost Catboost pip install catboost -i https://pypi.tuna.tsinghua.edu.cn/simple pip install ngboost -i https://pypi.tuna.tsinghua.edu.cn/simple pip install xgboost -i https://pypi.tuna.tsinghua.edu.cn/simple 数据比赛常用预测模型…

LeetCode MySQL 619. 只出现一次的最大数字

文章目录1. 题目2. 解题1. 题目 表 my_numbers 的 num 字段包含很多数字&#xff0c;其中包括很多重复的数字。 你能写一个 SQL 查询语句&#xff0c;找到只出现过一次的数字中&#xff0c;最大的一个数字吗&#xff1f; --- |num| --- | 8 | | 8 | | 3 | | 3 | | 1 | | 4 |…

幸福感数据分析与预测

文章目录分析目的一、数据采集1、 数据来源2、 数据说明二、数据传输三、数据处理1、查看数据2、缺失值处理3、合并数据集4、时间数据处理5、分组及One-hot编码处理四、数据分析1、描述性统计2、探索性分析1 是否与所在地是城市or农村有关2 是否与性别有关3 是否与年龄有关4 是…

LeetCode MySQL 1142. 过去30天的用户活动 II

文章目录1. 题目2. 解题1. 题目 Table: Activity ------------------------ | Column Name | Type | ------------------------ | user_id | int | | session_id | int | | activity_date | date | | activity_type | enum | ------------------…

mysql replace into用法详细说明

REPLACE的运行与INSERT很相似。只有一点例外&#xff0c;假如表中的一个旧记录与一个用于PRIMARY KEY或一个UNIQUE索引的新记录具有相同的值&#xff0c;则在新记录被插入之前&#xff0c;旧记录被删除。 注意&#xff0c;除非表有一个PRIMARY KEY或UNIQUE索引&#xff0c;否则…

MYSQL练习题

MYSQL练习题 数据表建立代码及题目解答 提取码&#xff1a;e6lk

LeetCode MySQL 1280. 学生们参加各科测试的次数

文章目录1. 题目2. 解题1. 题目 学生表: Students ------------------------ | Column Name | Type | ------------------------ | student_id | int | | student_name | varchar | ------------------------主键为 student_id&#xff08;学生ID&#xff09;&a…

【记录】有关parseInt的讨论

问题由来&#xff0c;某群的一个讨论&#xff1a; parseInt(1/0, 19) 18; parseInt的用法&#xff1a; parseInt(string [, radix]) 注意&#xff0c;第一个参数是String类型&#xff0c;当radix未指定的时候&#xff0c;那么默认基地是10。转换规则&#xff1a;1、首先查看位…

LeetCode MySQL 597. 好友申请 I :总体通过率

文章目录1. 题目2. 解题1. 题目 在 Facebook 或者 Twitter 这样的社交应用中&#xff0c;人们经常会发好友申请也会收到其他人的好友申请。现在给如下两个表&#xff1a; 表&#xff1a; friend_request | sender_id | send_to_id |request_date| |-----------|------------…

贷款利润最大化——利用随机森林和逻辑回归

文章目录分析目的一、数据采集1、数据来源2、数据说明二、数据传输三、数据处理1、查看数据2、清理无用特征值3、标签列分析4、清理只单一值的列5、空值处理6、数据类型转换四、数据挖掘1、构建模型2、导入算法五、总结分析目的 本文针对某信贷网站提供的2007-2011年贷款申请人…

ios学习之UITabBar(标签栏)

自定义TabBar的高度&#xff1a;&#xff08;无论横屏还是竖屏都以竖屏为准&#xff0c;之前就改为横屏的设置出错&#xff0c;找了好久才找到这个问题&#xff09; tabBar [[UITabBarController alloc] init];// 改变tabBarController高度 tabBar.tabBar.frameCGRectMake(0,…

LeetCode MySQL 512. 游戏玩法分析 II

文章目录1. 题目2. 解题1. 题目 Table: Activity ----------------------- | Column Name | Type | ----------------------- | player_id | int | | device_id | int | | event_date | date | | games_played | int | ----------------------- (…