AngularJS并沒有main方法,AngularJS使用模塊的概念來代替main方法澜掩。
加載和依賴
模塊加載動作發(fā)生在兩個不同的階段,這一點從函數(shù)名上面就可以反映出來,它們分別是Config代碼塊和Run代碼塊(或者叫做階段)宇挫。
Config代碼塊
在這一階段里面,AngularJS會連接并注冊好所有數(shù)據(jù)源酪术。
因此器瘪,只有數(shù)據(jù)源和常量
可以注入到Config代碼塊中。
那些不確定是否已經(jīng)初始化好的服務不能注入進來绘雁。
Run代碼塊
Run代碼塊用來啟動你的應用橡疼。
為了避免在開始之后再對系統(tǒng)進行配置操作,只有實例和常量
可以被注入到Run代碼塊中庐舟。
你會發(fā)現(xiàn)欣除,在AngularJS中,Run代碼塊是與main方法最類似的東西挪略。
快捷方法
利用模塊可以做什么呢历帚?我們可以用它來實例化控制器、指令杠娱、過濾器以及服務挽牢,但是利用模塊類還可以做更多事情。
如下模塊配置的API方法:
1.config(configFn)
利用此方法可以做一些注冊工作摊求,這些工作需要在模塊加載時完成禽拔。
2.constant(name, object)
此方法會首先運行,所以你可以用它來聲明整個應用范圍內(nèi)的常量
睹簇,并且讓它們在所有配置(config方法)和實例(后面的所有方法奏赘,例如controller、service等)方法中可用太惠。它經(jīng)常被用來在指令中提供默認配置磨淌。作為一個constant,我們放入其中的值將不會改變
凿渊。
3.controller(name,constructor)
它的基本作用是配置好控制器方便后面使用梁只。
4.directive(name,directiveFactory)
可以使用此方法在應用中創(chuàng)建指令。
5.filter(name,filterFactory)
允許你創(chuàng)建命名的AngularJS過濾器
埃脏。
6.run(initializationFn)
如果你想要在APP啟動之后執(zhí)行某些操作搪锣,而這些操作需要在頁面對用戶可用之前執(zhí)行,就可以使用此方法彩掐。
run的作用构舟,相當于去初始化一些全局的數(shù)據(jù),省略了控制器的環(huán)節(jié)堵幽,就可以直接把值掛載到全局作用域下狗超。
7.value(name,object)
允許在整個應用中注冊值弹澎。value service有點像是一個constant,但是它是可以被改變的努咐。它也經(jīng)常被用在一個指令上面苦蒿,來進行配置。一個value service有點像是一個factory service的縮小版渗稍,它經(jīng)常用來保存值但是我們不能在其中對值進行計算佩迟。
8.factory(name,factoryFn)
一個Factory是一個能夠返回任何數(shù)據(jù)類型的service。
對于你如何創(chuàng)建它并沒有什么要求竿屹,你僅僅需要在其中返回一些東西即可报强。
如果你有一個類或者對象,需要首先為它提供一些邏輯或者參數(shù)羔沙,然后才能對它初始化躺涝,那么你就可以使用這里的factory接口。
factory是一個函數(shù)扼雏,它負責創(chuàng)建一些特定的值(或者對象)坚嗜。
我們來看一個greeter(打招呼)函數(shù)的實例,這個函數(shù)需要一條問候語來初始化:
function Greeter(salutation) {
this.greet = function(name) {
return salutation + ' ' + name;
};
}
// greeter函數(shù)示例如下:
myApp.factory('greeter', function(salut) {
return new Greeter(salut);
});
// 然后可以這樣來調(diào)用它:
var myGreeter = greeter('Halo');
9.service(name,object)
factory和service之間的不同點在于诗充,factory會直接調(diào)用傳遞給它的函數(shù)苍蔬,然后返回執(zhí)行的結果;
而service將會使用"new"關鍵字來調(diào)用傳遞給它的構造方法蝴蜓,然后再返回結果碟绑。
所以,前面的greeter Factory可以替換成下面這個greeter Service:
myApp.service('greeter', Greeter);
每當我們需要一個greeter實例的時候茎匠,AngularJS就會調(diào)用新的Greeter()來返回一個實例格仲。
補充:下面兩個例子是等價的
app.service('foo', function() {
var thisIsPrivate = "Private";
this.variable = "This is public";
this.getPrivate = function() {
return thisIsPrivate;
};
});
//如果我們已經(jīng)有了一個類,并且我們想將它用在service中
//也可以這樣寫
app.service('foo3',Foobar);
app.factory('foo2', function() {
return new Foobar();
});
function Foobar() {
var thisIsPrivate = "Private";
this.variable = "This is public";
this.getPrivate = function() {
return thisIsPrivate;
};
}
10.provider(name,providerFn)
provider是這幾個方法中最復雜的部分(顯然诵冒,也是可配置性最好的部分)凯肋。
provider中既綁定了factory也綁定了service,并且在注入系統(tǒng)準備完畢之前汽馋,還可以享受到配置provider函數(shù)的好處(也就是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);
};
});
這樣我們就可以在運行時動態(tài)設置問候語了(例如,可以根據(jù)用戶使用的不同語言進行設置)豹芯。
var myApp = angular.module(myApp, [])
.config(function(greeterProvider) {
greeterProvider.setSalutation('Namaste');
});
補充:上一個例子中補充的factory代碼等價于下面的provider代碼:
app.provider('foo', function() {
return {
$get: function() {
var thisIsPrivate = "Private";
function getPrivate() {
return thisIsPrivate;
}
return {
variable: "This is public",
getPrivate: getPrivate
};
}
};
});
一個provider中應當有一個$get函數(shù)悄雅,其中的內(nèi)容就是我們想要注入我們應用中的部分。
因此當我們將foo注入一個控制器時铁蹈,我們實際上注入的是$get函數(shù)宽闲。
既然factory如此簡單,那我們?yōu)槭裁催€要使用provider呢?因為我們可以在config階段配置一個provider便锨。
我們可以編寫下面的代碼:
app.provider('foo', function() {
var thisIsPrivate = "Private";
return {
setPrivate: function(newVal) {
thisIsPrivate = newVal;
},
$get: function() {
function getPrivate() {
return thisIsPrivate;
}
return {
variable: "This is public",
getPrivate: getPrivate
};
}
};
});
app.config(function(fooProvider) {
fooProvider.setPrivate('New value from config');
});
在這里我們將thisIsPrivate移到了我們的$get函數(shù)的外面围辙,然后我們創(chuàng)建了一個setPrivate來在一個config函數(shù)中修改thisIsPrivate。
這比在factory中添加setter要容易放案,除此之外,我們可以用它來配置URL矫俺。