1.背景介紹
directive( )方法可以接受兩個(gè)參數(shù):
1. name(字符串)指令的名字,用來(lái)在視圖中引用特定的指令。
2. factory_function(函數(shù))? 這個(gè)函數(shù)返回一個(gè)對(duì)象,其中定義了指令的全部行為。 $compile服務(wù)利用這個(gè)方法返回的對(duì) 象,在DOM調(diào)用指令時(shí)來(lái)構(gòu)造指令的行為。
angular.application('myApp', [])
.directive('myDirective', function() {
//一個(gè)指令定義對(duì)象
? ? return {
//通過(guò)設(shè)置項(xiàng)來(lái)定義指令,在這里進(jìn)行覆寫(xiě)
? ? };
});
為了避免與未來(lái)的HTML標(biāo)準(zhǔn)沖突,給自定義的指令加入前綴來(lái)代表自定義的 命名空間。AngularJS本身已經(jīng)使用了 ng-前綴,所以可以選擇除此以外的名字。 在例子中我們使用 my-前綴(比如 my-derictive)。當(dāng)模板在上面代碼中返回時(shí),你可以把以下的屬性列表應(yīng)用于指令定義返回的對(duì)象? ? ? ? ? ?
restrict(字符串)? ? ? ? ? ?
restrict是一個(gè)可選的參數(shù)。它告訴AngularJS這個(gè)指令在DOM中可以何種形式被聲明。默? 認(rèn)AngularJS認(rèn)為 restrict的值是 A,即以屬性的形式來(lái)進(jìn)行聲明。
可選值如下:
? ? ? ? ? ? restrict值可以是以下幾種:
? ? ? ? ? ? E作為元素名使用
? ? ? ? ? ? A作為屬性使用
? ? ? ? ? ? C作為類(lèi)名使用
? ? ? ? ? ? M作為注釋使用
template(字符串或函數(shù))
template參數(shù)是可選的,必須被設(shè)置為以下兩種形式之一:? ? ? ? ??
? 一個(gè)可以接受兩個(gè)參數(shù)的函數(shù),參數(shù)為 tElement和 tAttrs,并返回一個(gè)代表模板的字符
串。
templateUrl(字符串或函數(shù))。templateUrl是可選的參數(shù),可以是以下類(lèi)型:
? 一個(gè)代表外部HTML文件路徑的字符串;
指令中的scope
directive默認(rèn)能共享父 scope中定義的屬性,例如在模版中直接使用父 scope中的對(duì)象和屬性。
? ? ? ? ? ? ? ? ? ? 通常使用這種直接共享的方式可以實(shí)現(xiàn)一些簡(jiǎn)單的 directive功能。但是當(dāng)要?jiǎng)?chuàng)建一個(gè)可以重復(fù)使用的directive的時(shí)候,
? ? ? ? ? ? ? ? ? ? 就不能依賴(lài)于父scope了,因?yàn)樵诓煌牡胤绞褂胐irective對(duì)應(yīng)的父scope不一樣。所以需要一個(gè)隔離的scope,我們可以向
? ? ? ? ? ? ? ? ? ? 下面這樣來(lái)定義我們的scope。
scope = false
在指令模板中可以直接使用父作用域中的變量,函數(shù)。指令繼承了父作用域的一切屬性和方法,這也使得在指令的模板中我們可以使用這些屬性和方法。
? ? ? ? ? ? ? ? ? ? 將scope設(shè)置為false的時(shí)候,我們創(chuàng)建的指令和父作用域(其實(shí)是同一個(gè)作用域)共享同一個(gè)model模型,所以在指令中修改模型數(shù)據(jù),它會(huì)反映到父作用域的模型中
scope = true
當(dāng)把scope屬性設(shè)置為true時(shí),表明我們創(chuàng)建的指令要?jiǎng)?chuàng)建一個(gè)新的作用域,這個(gè)作用域是繼承了父作用域。
scope = {}
指令將創(chuàng)建完全獨(dú)立的作用域,當(dāng)我們將scope設(shè)置為{}時(shí),意味著我們創(chuàng)建的一個(gè)新的與父作用域隔離的新的作用域,這使我們?cè)诓恢劳獠凯h(huán)境的情況下,? 就可以正常工作,不依賴(lài)外部環(huán)境。指令的這個(gè)屬性讓AngularJS變得最強(qiáng),它可以構(gòu)建組建,無(wú)論放在哪里都是可以使用。
但是我們使用了隔離的作用域,不代表我們不可以使用父作用域的屬性和方法。我們可以通過(guò)向scope的{}中傳入特殊的前綴標(biāo)識(shí)符(即prefix),來(lái)進(jìn)行數(shù)據(jù)的綁定。
? ? ? ? ? ? ? ? @
? ? ? ? ? ? ? ? 這是一個(gè)單項(xiàng)綁定的前綴標(biāo)識(shí)符?
? ? ? ? ? ? ? ? 使用方法:在元素中使用屬性,好比這樣 my-name="{{name}}",注意,屬性的名字要用-將兩個(gè)單詞? ? ? ? ? ? ? ? ? 連接,因?yàn)槭菙?shù)據(jù)的單項(xiàng)綁定所以要通過(guò)使用{{}}來(lái)綁定數(shù)據(jù)。
? ? ? ? ? ? ? ? =
? ? ? ? ? ? ? ? 這是一個(gè)雙向數(shù)據(jù)綁定前綴標(biāo)識(shí)符
? ? ? ? ? ? ? ? 使用方法:在元素中使用屬性,好比這樣? my-age="age",注意,數(shù)據(jù)的雙向綁定要通過(guò)=前綴標(biāo)識(shí)符? ? ? ? ? ? ? ? ? 實(shí)現(xiàn),所以不可以使用{{}}。
? ? ? ? ? ? ? ? &
? ? ? ? ? ? ? ? 這是一個(gè)綁定函數(shù)方法的前綴標(biāo)識(shí)符
? ? ? ? ? ? ? ? 使用方法:在元素中使用屬性,好比這樣 my-change="changeAge()",注意,屬性的名字要用-將多? ? ? ? ? ? ? ? ?個(gè)個(gè)單詞連接。
指令中的 controller , compile , link函數(shù)
AngularJs的生命周期;分為兩個(gè)階段:
? ? ? ? ? ? ? ? ? ? 第一個(gè)階段是編譯階段:
? ? ? ? ? ? ? ? ? ?在編譯階段,AngularJS會(huì)遍歷整個(gè)HTML文檔并根據(jù)JavaScript中的指令定義來(lái)處理頁(yè)面上聲明的指 令。每一個(gè)指令的模板中都可能含
? ? ? ? ? ? ? ? ? ? 有另外一個(gè)指令,另外一個(gè)指令也可能會(huì)有自己的模板。當(dāng)AngularJS調(diào)用HTML文檔根部的指令時(shí),會(huì)遍歷其中所有的模板,模板中也可能包
? ? ? ? ? ? ? ? ? ? 含帶有模板的指令.一旦對(duì)指令和其中的子模板進(jìn)行遍歷或編譯,編譯后的模板會(huì)返回一個(gè)叫做模板函數(shù)的函數(shù)。我們有機(jī)會(huì)在指令的模板函
? ? ? ? ? ? ? ? ? ? 數(shù)被返回前,對(duì)編譯后的DOM樹(shù)進(jìn)行修改。
? ? ? ? ? ? ? ? 第二個(gè)階段是鏈接階段:鏈接函數(shù)來(lái)將模板與作用域鏈接起來(lái);負(fù)責(zé)設(shè)置事件監(jiān)聽(tīng)器,監(jiān)視數(shù)據(jù)變化和實(shí)時(shí)的操作DOM.鏈接函數(shù)是可選的。
如果定義了編譯函數(shù),它會(huì)返回鏈接函數(shù),因此當(dāng)兩個(gè)函數(shù)都定義了時(shí),編譯函數(shù)會(huì)重載鏈接函數(shù)
指令的控制器和link函數(shù)可以進(jìn)行互換??刂破髦饕怯脕?lái)提供可在指令間復(fù)用的行為,但鏈接函數(shù)只能在當(dāng)前內(nèi)部指令中定義行為,
? ? ? ? ? ? ? ? ? ? 且無(wú)法在指令間復(fù)用.link函數(shù)可以將指令互相隔離開(kāi)來(lái),而controller則定義可復(fù)用的行為。
1、link和controller的區(qū)別:post級(jí)別最高幾個(gè)函數(shù)同時(shí)存在name為post的name,也就是post最后執(zhí)行。compile函數(shù)最先執(zhí)行,然后是controller,接著是pre,最后是post。有compile時(shí) link不執(zhí)行。沒(méi)有compile時(shí),controller先執(zhí)行,link后執(zhí)行。
2、什么時(shí)候使用compile: 在編譯的階段,angularJs會(huì)遍歷整個(gè)的文檔并根據(jù)JavaScript中指令定義來(lái)處理頁(yè)面上什么的指令。在遍歷的過(guò)程中,有可能一層套著一層,一直延深處遍歷。一但遍歷和編譯完畢就會(huì)返回一個(gè)叫做模板函數(shù)的函數(shù)。在這個(gè)函數(shù)沒(méi)被返回(return)之前我們可以對(duì)編譯后的DOM樹(shù)進(jìn)行修改。通常情況下,如果設(shè)置了compile函數(shù),說(shuō)明我們希望在指令和實(shí)時(shí)數(shù)據(jù)被放到DOM中之前進(jìn)行DOM操作,在這個(gè)函數(shù)中進(jìn)行諸如添加和刪除節(jié)點(diǎn)等DOM操作是安全的。本質(zhì)上,當(dāng)我們?cè)O(shè)置了link選項(xiàng),實(shí)際上是創(chuàng)建了一個(gè)postLink()?鏈接函數(shù),以便compile()?函數(shù)可以定義鏈接函數(shù)。編譯函數(shù)(compile)負(fù)責(zé)對(duì)模板DOM進(jìn)行轉(zhuǎn)換。鏈接函數(shù)(link)負(fù)責(zé)將作用域和DOM進(jìn)行鏈接。
3、prlority:優(yōu)先權(quán),權(quán)重高的指令先執(zhí)行