標籤:style class blog code java http
概述
如果你寫過AngularJS的應用,那麼你一定已經使用過指令,不管你有沒有意識到。你肯定已經用過簡單的指令,比如 ng-mode, ng-repeat, ng-show等。這些指令都賦予DOM元素特定的行為。例如,ng-repeat 重複特定的元素,ng-show 有條件地顯示一個元素。如果你想讓一個元素支援拖拽,你也需要建立一個指令來實現它。
指令基本思想:它通過對元素繫結事件監聽或者改變DOM而使HTML擁有真實的互動性。
Link函數和Scope
指令產生出的模板其實沒有太多意義,除非它在特定的scope下編譯。預設情況下,指令並不會建立新的子scope。更多的,它使用父scope。也就是說,如果指令存在於一個controller下,它就會使用這個controller的scope。 如何運用scope,我們要用到一個叫做 link 的函數。它由指令定義對象中的link屬性配置。讓我們來改變一下我們的 helloWorld 指令,當使用者在一個輸入框中輸入一種顏色的名稱時,Hello World 文字的背景色自動發生變化。同時,當使用者在 Hello World 文字上點擊時,背景色變回白色。 相應的HTML標記如下:
1 <body ng-controller="MainCtrl">2 <input type="text" ng-model="color" placeholder="Enter a color" />3 <hello-world/>4 </body>
helloWorld 指令如下:
1 app.directive(‘helloWorld‘, function() { 2 return { 3 restrict: ‘AE‘, 4 replace: true, 5 template: ‘<p style="background-color:{{color}}">Hello World‘, 6 link: function(scope, elem, attrs) { 7 elem.bind(‘click‘, function() { 8 elem.css(‘background-color‘, ‘white‘); 9 scope.$apply(function() {10 scope.color = "white";11 });12 });13 elem.bind(‘mouseover‘, function() {14 elem.css(‘cursor‘, ‘pointer‘);15 });16 }17 };18 });
- scope – 指令的scope。在我們的例子中,指令的scope就是父controller的scope。
- elem – 指令的jQLite(jQuery的子集)封裝DOM元素。如果你在引入AngularJS之前引入了jQuery,那麼這個元素就是jQuery元素,而不是jQLite元素。由於這個元素已經被jQuery/jQLite封裝了,所以我們就在進行DOM操作的時候就不需要再使用 $()來進行封裝。
- attr – 一個包含了指令所在元素的屬性的標準化的參數對象。舉個例子,你給一個HTML元素添加了一些屬性:,那麼可以在 link 函數中通過 attrs.someAttribute 來使用它。
click 處理函數用來重設 <p> 的背景色,而 mouseover 處理函數改變滑鼠為 pointer。在模板中有一個運算式 {{color}},當父scope中的 color 發生變化時,它用來改變 Hello World 文字的背景色。線上示範:http://plnkr.co/edit/14q6WxHyhWuVxEIqwww1
link函數:主要用來為DOM元素添加事件監聽、監視模型屬性變化、以及更新DOM
指令是如何被編譯的
當應用引導啟動的時候,Angular開始使用 $compile 服務遍曆DOM元素。這個服務基於註冊過的指令在標記文本中搜尋指令。一旦所有的指令都被識別後,Angular執行他們的 compile 方法。如前面所講的,compile 方法返回一個 link 函數,被添加到稍後執行的 link 函數列表中。這被稱為編譯階段。如果一個指令需要被複製很多次(比如 ng-repeat),compile函數只在編譯階段被執行一次,複製這些模板,但是link 函數會針對每個被複製的執行個體被執行。所以分開處理,讓我們在效能上有一定的提高。這也說明了為什麼在 compile 函數中不能訪問到scope對象。 在編譯階段之後,就開始了連結(linking)階段。在這個階段,所有收集的 link 函數將被一一執行。指令創造出來的模板會在正確的scope下被解析和處理,然後返回具有事件響應的真實的DOM節點。
Demo:https://github.com/jsprodotcom/source/blob/master/AngularJS_Note_Taker-source_code.zip
http://embed.plnkr.co/QvxI4LbqfUY3C3XQjN3m/app.js
原文連結: sitepoint
譯文連結: http://blog.jobbole.com/62999/