AngularJs Modules詳解及示例代碼
一、什么是Module?
很多應(yīng)用都有一個用于初始化、加載(wires是這個意思嗎?)和啟動應(yīng)用的main方法。angular應(yīng)用不需要main方法,作為替代,module提供有指定目的的聲明式,描述應(yīng)用如何啟動。這樣做有幾項優(yōu)點:
- 這過程是聲明描述的,更加容易讀懂。
- 在單元測試中,不需要加載所有module,這對寫單元測試很有幫助。
- 額外的module可以被加載到情景測試中,可以覆蓋一些設(shè)置,幫助進行應(yīng)用的端對端測試(end-to-end test)。
- 第三方代碼可以作為可復(fù)用的module打包到angular中。
- module可以通過任意順序或并行加載(取決于模塊執(zhí)行的延遲性,due to delayed nature of module execution)。
二、The Basics(基礎(chǔ))
我們很迫切想知道如何讓Hello World module能夠工作。下面有幾個關(guān)鍵的事情要注意:
module API(http://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)推薦設(shè)置
雖然上面的例子很簡單,它不屬于大規(guī)模的應(yīng)用。我們建議將自己的應(yīng)用按照如下建議,拆分為多個module:
- service module,用于聲明service。
- directive module,用于聲明directive。
- filter module,用于聲明filter。
- 應(yīng)用級別的module,依賴上述的module,并且包含初始化的代碼。
這樣劃分的理由是,當(dāng)我們在測試的時候,往往需要忽略那些讓測試變得困難的初始化代碼。通過將代碼分成獨立的module,在測試中就可以很容易地忽略那些代碼。這樣,我們就可以更加專注在加載相應(yīng)的module進行測試。
上面的只是一個建議,可以隨意地按照自己的需求制定。
四、Module Loading & Dependencies(模塊加載和依賴)
module是配置(configuration)的集合,執(zhí)行在啟動應(yīng)用的進程中應(yīng)用的塊(blocks)。在它的最簡單的形式中,由兩類block組成:
1.配置塊(configuration blocks):在provider注冊和配置的過程中執(zhí)行的。只有provider和constant(常量?)可以被注入(injected)到configuration blocks中。這是為了避免出現(xiàn)在service配置完畢之前service就被執(zhí)行的意外。
2.運行塊(run blocks):在injector創(chuàng)建完成后執(zhí)行,用于啟動應(yīng)用。只有實例(instances)和常量(constants)可以被注入到run block中。這是為了避免進一步的系統(tǒng)配置在程序運行的過程中執(zhí)行。
angular.module('myModule', []).
config(function(injectables) { // provider-injector
// 這里是config block的一個例子
// 我們可以根據(jù)需要,弄N個這樣的東東
// 我們可以在這里注入Providers (不是實例,not instances)到config block里面
}).
run(function(injectables) { // instance-injector
// 這里是一個run block的例子
// 我們可以根據(jù)需要,弄N個這樣的東東
// 我們只能注入實例(instances )(不是Providers)到run block里面
});
a) Configuration Blocks(配置塊)
有一個方便的方法在module中,它相當(dāng)于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被應(yīng)用的順序,與它們的注冊的順序一致。對于常量定義來說,是一種額外的情況,即放置在configuration blocks開頭的常量定義。
b) Run Blocks(應(yīng)用塊)
run block是在angular中最接近main方法的東東。run block是必須執(zhí)行,用于啟動應(yīng)用的代碼。它將會在所有service配置、injector創(chuàng)建完畢后執(zhí)行。run block通常包含那些比較難以進行單元測試的代碼,就是因為這個原因,這些代碼應(yīng)該定義在一個獨立的module中,讓這些代碼可以在單元測試中被忽略。
c) Dependencies(依賴)
一個module可以列出它所依賴的其他module。依賴一個module,意味著被請求(required)的module(被依賴的)必須在進行請求(requiring)module(需要依賴其他module的module,請求方)加載之前加載完成。換一種說法,被請求的module的configuration block會在請求的module的configuration block執(zhí)行前執(zhí)行(before the configuration blocks or the requiring module,這里的or怎么解釋呢?)。對于run block也是這個道理。每一個module只能夠被加載一次,即使有多個其他module需要(require)它。
d) Asynchronous Loading(異步加載)
module是管理$injector配置的方法之一,不用對加載腳本到VM做任何事情?,F(xiàn)在已經(jīng)有現(xiàn)成的項目專門用于處理腳本加載,也可以用到angular中。因為module在加載的過程中不做任何事情,它們可以按照任意的順序被加載到VM中。腳本加載器可以利用這個特性,進行并行加載。
五、Unit Testing(單元測試)
在單元測試的最簡單的形式中,其中一個是在測試中實例化一個應(yīng)用的子集,然后運行它們。重要的是,我們需要意識到對于每一個injector,每一個module只會被加載一次。通常一個應(yīng)用只會有一個injector。但在測試中,每一個測試用例都有它的injector,這意味著在每一個VM中,module會被多次加載。正確地構(gòu)建module,將對單元測試有幫助,正如下面的例子:
在這個例子中,我們準備假設(shè)定義如下的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() {
// 加載應(yīng)用響應(yīng)的module,然后加載指定的將$window重寫為mock版本的測試module,
// 這樣做,當(dāng)進行window.alert()時,測試器就不會因被真正的alert窗口阻擋而停止
//這里是一個在測試中覆蓋配置信息的例子
beforeEach(module('greetMod', function($provide) {//這里看來是要將真正的$window替換為以下的東東
$provide.value('$window', {
alert: jasmine.createSpy('alert')
});
}));
// inject()會創(chuàng)建一個injector,并且注入greet和$window到測試中。
// 測試不需要關(guān)心如何寫應(yīng)用,只需要關(guān)注如何測試應(yīng)用。
it('should alert on $window', inject(function(greet, $window) {
greet('World');
expect($window.alert).toHaveBeenCalledWith('Hello World!');
}));
// 這里是在測試中通過行內(nèi)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!');
});
});
});
- Angular 理解module和injector,即依賴注入
- 深入淺析AngularJS中的module(模塊)
- 詳解AngularJS中module模塊的導(dǎo)入導(dǎo)出
- AngularJS Module方法詳解
- Angular ng-repeat 對象和數(shù)組遍歷實例
- 基于AngularJS實現(xiàn)iOS8自帶的計算器
- 微信+angularJS的SPA應(yīng)用中用router進行頁面跳轉(zhuǎn),jssdk校驗失敗問題解決
- AngularJS 實現(xiàn)JavaScript 動畫效果詳解
- 深入理解AngularJS中的ng-bind-html指令和$sce服務(wù)
- Angular Module聲明和獲取重載實例代碼
相關(guān)文章
詳解Angular4中路由Router類的跳轉(zhuǎn)navigate
這篇文章主要介紹了詳解Angular4中路由Router類的跳轉(zhuǎn)navigate,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
Angularjs+bootstrap+table多選(全選)支持單擊行選中實現(xiàn)編輯、刪除功能
這篇文章主要介紹了Angularjs bootstrap table多選(全選)支持單擊行選中實現(xiàn)編輯、刪除功能,需要的朋友可以參考下2017-03-03
AngularJS service之select下拉菜單效果
這篇文章主要為大家詳細介紹了AngularJS service之select下拉菜單效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
Angularjs的ng-repeat中去除重復(fù)數(shù)據(jù)的方法
這篇文章主要介紹了Angularjs的ng-repeat中去除重復(fù)數(shù)據(jù)的方法,涉及AngularJS針對重復(fù)數(shù)據(jù)的遍歷與過濾技巧,需要的朋友可以參考下2016-08-08
Angular實現(xiàn)可刪除并計算總金額的購物車功能示例
這篇文章主要介紹了Angular實現(xiàn)可刪除并計算總金額的購物車功能,涉及AngularJS事件響應(yīng)、元素遍歷與數(shù)值運算等相關(guān)操作技巧,需要的朋友可以參考下2017-12-12

