如何理解ANGOLAR自定義指令DIRECTIVE的COMPILE、LINK屬性?

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.編碼實戰

DEMO1


6.擴展思考

幾個指令嵌套時compile中pre-link,post-link的執行順序?

DEMO2


7.參考文獻

參考一:流浪貓の窩-angular學習筆記(三十)-指令(7)-compile和link

參考二:呂大豹-走進AngularJs(三)自定義指令


8.更多討論

1.為什么為什么編譯的過程要分成compile和link?

? ? ? ? 簡單的說就是為了解決性能問題,特別是那種model變化會影響dom結構變化的,而變化的結構還會有新的scope綁定及事件綁定,比如ng-repeat。


2.compile和link的使用時機?

? ? ? ? Compile:想在dom渲染前對它進行變形,并且不需要scope參數想在所有相同directive里共享某些方法,這時應該定義在compile里,性能會比較好返回值就是link的function,這時就是共同使用的時候

? ? ? ?Link:對特定的元素注冊事件需要用到scope參數來實現dom元素的一些行為

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容