1.背景介紹
? ? ? ? 指令是angularjs最重要的特性之一,通過自定義指令,我們可以將html與js封裝成一個獨立的模塊,使HTML標簽的范圍擴展到無窮大。在directive,compile和link是其最重要的兩個屬性。
2.知識剖析
自定義指令的基本結構:
dirAppModole.directive('directive-name',function(){
var obj = {
restrict:'string',
priority:number,
template:'string',
templateUrl:'string',
replace:bool,
transclude:bool or 'element',
scope:bool or string,
controller:function(){},
require:'string',
link: function(scope,iEle,iAttrs,ctrl,linker){},
compile: function(tEle,tAttrs,linker){
return {
pre: function(scope,iEle,iAttrs,ctrl){},
post: function(scope,iEle,iAttrs,ctrl){}
}
}
};
return obj
});
link函數:
link:function(scope,iEle,iAttrs,ctrl,linker){
....
}
如上,link有5個參數::scope,iEle,iAttrs,ctrl,linker
1.scope:指令所在的作用域,這個scope和指令定義的scope屬性是一致的.
2.iEle:指令元素本身,可進行jq操作
3.iAttrs:指令元素的屬性的集合
4.ctrl:需要和require屬性一起使用,用于調用其他指令的方法,指令之間的互相通信,
5.linker:即transclude()函數,自定義指令的transclude屬性有關。
compile函數:
compile函數有三個參數:tEle,tAttrs,linker:
1.tEle:指令元素本身,可進行jq操作.
2.tAttrs:指令元素的屬性的集合
3.linker函數:即transclude()函數.
compile的返回值:compile函數返回值有兩種可能:
1.返回pre-link函數和post-link函數
2.只返回post-link函數
3.常見問題
compile和link有什么不同?
4.解決方案
要解決這個問題需從指令的解析流程講起:
? ? ? ?1.ng框架會在頁面載入完畢的時候,根據ng-app劃定的作用域來調用$compile服務進行編譯,清點作用域內的DOM元素,然后根據這些指令的優先級(priority)
排列一下,根據指令中的配置參數(template,transclude等)轉換DOM,讓指令“初具人形”。
? ? ? ?2.然后就開始按順序執行各指令內的compile函數,注意此處的compile不是$compile,compile函數中可以訪問到DOM節點并進行操作,其主要職責就是進行
DOM轉換,每個compile函數執行完后都會返回compile內的link函數,這些link函數會被$compile匯合一下組合成一個合體后的link函數。
? ? ? ? 3.接下來進入link階段,合體后的link函數被執行。所謂的鏈接,就是把view和scope鏈接起來。這就是我們熟悉的數據綁定,通過在DOM上注冊監聽器來動態修改
scope中的數據,或者是使用$watchs監聽scope中的變量來修改DOM,從而建立雙向綁定。由此也可以斷定,合體的link可以訪問到scope和DOM節點。
? ? ? ? 4.若沒有配置compile函數?$compile就把這里的link函數拿來執行。配置的link函數也可以訪問到scope以及DOM節點。compile
函數通常是不會被配置的,因為我們定義一個指令的時候,大部分情況不會通過編程的方式進行DOM操作,而更多的是進行監聽器的注冊、數據的綁定。
? ? ? ?由上可知,compile與link不能共存,兩者的參數中都有ele,都是獲取指令元素本身,不同的是,compile拿到的是編譯前的,是從template里拿過來的,而link拿到的是編譯后的,已經與作用域建立了關聯,這也正是link中可以進行數據綁定的原因。
5.編碼實戰
6.擴展思考
幾個指令嵌套時compile中pre-link,post-link的執行順序?
7.參考文獻
參考一:流浪貓の窩-angular學習筆記(三十)-指令(7)-compile和link
8.更多討論
1.為什么為什么編譯的過程要分成compile和link?
? ? ? ? 簡單的說就是為了解決性能問題,特別是那種model變化會影響dom結構變化的,而變化的結構還會有新的scope綁定及事件綁定,比如ng-repeat。
2.compile和link的使用時機?
? ? ? ? Compile:想在dom渲染前對它進行變形,并且不需要scope參數想在所有相同directive里共享某些方法,這時應該定義在compile里,性能會比較好返回值就是link的function,這時就是共同使用的時候
? ? ? ?Link:對特定的元素注冊事件需要用到scope參數來實現dom元素的一些行為