angular的生命周期 21

1、編譯階段

第一個階段是編譯階段。在編譯階段,AngularJS會遍歷整個HTML文檔并根據JavaScript中的指令定義來處理頁面上聲明的指令。

一旦對指令和其中的子模板進行遍歷或編譯,編譯后的模板會返回一個叫做模板函數的函數。我們有機會在指令的模板函數被返回前,對編譯后的DOM樹進行修改。

在這個時間點DOM樹還沒有進行數據綁定,意味著如果此時對DOM樹進行操作只會有很少的性能開銷。基于此點, ng-repeat和ng-transclude等內置指令會在這個時候,也就是還未與任何作用域數據進行綁定時對DOM進行操作。

?

2、compile(對象或函數)

compile選項可以返回一個對象或函數。

compile選項本身并不會被頻繁使用,但是link函數則會被經常使用。本質上,當我們設置了link選項,實際上是創建了一個postLink()鏈接函數,以便compile()函數可以定義鏈接函數。

通常情況下,如果設置了compile函數,說明我們希望在指令和實時數據被放到DOM中之前進行DOM操作,在這個函數中進行諸如添加和刪除節點等DOM操作是安全的。

注:compile和link選項是互斥的。如果同時設置了這兩個選項,那么會把compile所返回的函數當作鏈接函數,而link選項本身則會被忽略。

不要進行DOM事件監聽器的注冊:這個操作應該在鏈接函數中完成。

compile: function(tEle, tAttrs, transcludeFn) {

var tplEl = angular.element('

' +'

' +'

');

var h2 = tplEl.find('h2');

h2.attr('type', tAttrs.type);

h2.attr('ng-model', tAttrs.ngModel);

h2.val("hello");

tEle.replaceWith(tplEl);

return function(scope, ele, attrs) {

// 連接函數

};

}

編譯函數負責對模板DOM進行轉換。

鏈接函數負責將作用域和DOM進行鏈接。

3、鏈接

用link函數創建可以操作DOM的指令。

鏈接函數是可選的。如果定義了編譯函數,它會返回鏈接函數,因此當兩個函數都定義了時,編譯函數會重載鏈接函數。如果我們的指令很簡單,并且不需要額外的設置,可以從工廠函數 (回

調函數)返回一個函數來代替對象。如果這樣做了,這個函數就是鏈接函數。

下面兩種定義指令的方式在功能上是完全一樣的:

angular.module('myApp', [])

.directive('myDirective', function() {

return {

pre: function(tElement, tAttrs, transclude) {

// 在子元素被鏈接之前執行

// 在這里進行Don轉換不安全

// 之后調用'lihk'h函數將無法定位要鏈接的元素

},

post: function(scope, iElement, iAttrs, controller) {

// 在子元素被鏈接之后執行

// 如果在這里省略掉編譯選項

//在這里執行DOM轉換和鏈接函數一樣安全嗎

}

};

});

angular.module('myApp', [])

.directive('myDirective', function() {

return {

link: function(scope, ele, attrs) {

return {

pre: function(tElement, tAttrs, transclude) {

// 在子元素被鏈接之前執行

// 在這里進行Don轉換不安全

// 之后調用'lihk'h函數將無法定位要鏈接的元素

},

post: function(scope, iElement, iAttrs, controller) {

// 在子元素被鏈接之后執行

// 如果在這里省略掉編譯選項

//在這里執行DOM轉換和鏈接函數一樣安全嗎

}

}

}

});

如果你編寫自定義的compile函數,則自定義的link函數無效應為compile會返回一個link函數

下面看一下鏈接函數中的參數:

scope

指令用來在其內部注冊監聽器的作用域。

iElement

iElement參數代表實例元素,指使用此指令的元素。在postLink函數中我們應該只操作此元素的子元素,因為子元素已經被鏈接過了。

iAttrs

iAttrs參數代表實例屬性,是一個由定義在元素上的屬性組成的標準化列表,可以在所有指令的鏈接函數間共享。會以javascript對象的形式進行傳遞。

controller

controller 參 數 指 向 require 選 項 定 義 的 控 制 器 。 如 果 沒 有 設 置 require 選 項 , 那 么controller參數的值為undefined。

控制器在所有的指令間共享,因此指令可以將控制器當作通信通道(公共API)。如果設置了多個require,那么這個參數會是一個由控制器實例組成的數組,而不只是一個單獨的控制器。

總結:

(1)compile函數的作用就是對指令的模板函數進行轉換。

(2)link函數是在模型和視圖之間建立關聯,包括在元素上注冊監聽事件。

(3)scope在連接階段才被綁定到元素上,所以在compile階段操作scope回報錯誤。

(4)一般情況下,我們只寫link函數就夠了。

(5)請注意,如果你編寫自定義的compile函數,則自定義的link函數無效應為compile會返回一個link函數

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

推薦閱讀更多精彩內容