本教程使用AngularJs版本:1.5.3
AngularJs GitHub: https://github.com/angular/angular.js/
AngularJs下載地址:https://angularjs.org/
摘要: Directive(指令)筆者認為是AngularJ非常強大而有有用的功能之一。它就相當於為我們寫了公共的自定義DOM元素或CLASS屬性或ATTR屬性,並且它不只是單單如此,你還可以在它的基礎上來操作scope、綁定事件、更改樣式等。通過這個Directive,我們可以封裝很多公共指令,比如分頁指令、自動補全指令等等。然後在HTML頁面裡只需要簡單的寫一行代碼就可以實現很多強大的功能。一般情況下,需要用Directive有下面的情景:
1. 使你的Html更具語義化,不需要深入研究代碼和邏輯即可知道頁面的大致邏輯。
2. 抽像一個自定義組件,在其他地方進行重用。
一、Directive的定義及其使用方法
AngularJs的指令定義大致如下
angular.module("app",[]).directive("directiveName",function(){ return{ //通過設置項來定義}; })Directive可以放置於元素名、屬性、class、註釋中。下面是引用myDir這個directive的等價方式。 (但很多directive都限制為“屬性”的使用方式)
<span <span style="font-family: Arial, Helvetica, sans-serif;">directive-name</span><span style="font-family: Arial, Helvetica, sans-serif;">="exp"></span>//屬性</span> <spanfont-family: Arial, Helvetica, sans-serif;">directive-name</span>: exp;"></span>//class <<span style="font-family: Arial, Helvetica, sans-serif;">directive-name</span>></<span style="font-family: Arial, Helvetica, sans-serif;">directive-name</span>>//元素<!-- directive: <span style="font-family: Arial, Helvetica, sans-serif;">directive-name </span><span style="font-family: Arial, Helvetica, sans-serif;">exp -->//註釋</span>
如下一個實例:
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <hello-world></hello-world> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.directive('helloWorld', function() { return { restrict: 'E', template: '<div>Hi 我是林炳文~~~</div>', replace: true }; }); </script> </html>結果:
下面是一個directive的詳細版
var myModule = angular.module(...); myModule.directive('directiveName', function factory(injectables) { var directiveDefinitionObject = { priority: 0, template: '<div></div>', templateUrl: 'directive.html', replace: false, transclude: false, restrict: 'A', scope: false, compile: function compile(tElement, tAttrs, transclude) { return { pre: function preLink(scope, iElement, iAttrs, controller) { ... }, post: function postLink(scope, iElement, iAttrs, controller) { ... } } }, link: function postLink(scope, iElement, iAttrs) { ... } }; return directiveDefinitionObject; });二、Directive指令內容解讀
可以看到它有8個內容
1.restrict
(字符串)可選參數,指明指令在DOM裡面以什麼形式被聲明;取值有:E(元素),A(屬性),C(類),M(註釋),其中默認值為A;當然也可以兩個一起用,比如EA.表示即可以是元素也可以是屬性。
[html] view plain copy 在CODE上查看代碼片派生到我的代碼片
E(元素):<directiveName></directiveName>
A(屬性):<div directiveName='expression'></div>
C(類): <div class='directiveName'></div>
M(註釋):<--directive:directiveName expression-->
一般情況下E/A/C用得比較多。
2.priority
(數字),可選參數,指明指令的優先級,若在單個DOM上有多個指令,則優先級高的先執行;
3.terminal
(布爾型),可選參數,可以被設置為true或false,若設置為true,則優先級低於此指令的其他指令則無效,不會被調用(優先級相同的還是會執行)
4.template(字符串或者函數)可選參數,可以是:
(1)一段HTML文本
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <hello-world></hello-world> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.directive('helloWorld', function() { return { restrict: 'E', template: '<div><h1>Hi 我是林炳文~~~</h1></div>', replace: true }; }); </script> </html>(2)一個函數,可接受兩個參數tElement和tAttrs
其中tElement是指使用此指令的元素,而tAttrs則實例的屬性,它是一個由元素上所有的屬性組成的集合(對象)形如:
<hello-world2 title = '我是第二個directive'></hello-world2>
其中title就是tattrs上的屬性
下面讓我們看看template是一個函數時候的情況
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <hello-world></hello-world> <hello-world2 title = '我是第二個directive'></hello-world2> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.directive('helloWorld', function() { return { restrict: 'E', template: '<div><h1>Hi 我是林炳文~~~</h1></div>', replace: true }; }); app.directive("helloWorld2",function(){ return{ restrict:'EAC', template: function(tElement,tAttrs){ var _html = ''; _html += '<div>' +'hello '+tAttrs.title+'</div>'; return _html; } }; }); </script> </html>結果:
可以看到指令中還用到了hello-world2中的標籤中的title字段
5.templateUrl(字符串或者函數),可選參數,可以是
(1)一個代表HTML文件路徑的字符串
(2)一個函數,可接受兩個參數tElement和tAttrs(大致同上)
注意:在本地開發時候,需要運行一個服務器,不然使用templateUrl會報錯Cross Origin Request Script(CORS)錯誤。由於加載html模板是通過異步加載的,若加載大量的模板會拖慢網站的速度,這裡有個技巧,就是先緩存模板
你可以再你的index頁面加載好的,將下列代碼作為你頁面的一部分包含在裡面。
<script type='text/ng-template' id='hello.html'> <div><h1>Hi 我是林炳文~~~</h1></div> </script>
這裡的id屬性就是被設置在templateUrl上用的。
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <hello-world></hello-world> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.directive('helloWorld', function() { return { restrict: 'E', templateUrl: 'hello.html', replace: true }; }); </script> <script type='text/ng-template' id='hello.html'> <div><h1>Hi 我是林炳文~~~</h1></div> </script> </html>輸出結果:
另一種辦法緩存是:
app.run(["$templateCache", function($templateCache) { $templateCache.put("hello.html", "<div><h1>Hi 我是林炳文~~~</h1></div>"); }]);使用實例如下:
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <hello-world></hello-world> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.directive('helloWorld', function() { return { restrict: 'E', templateUrl: 'hello.html', replace: true }; }); app.run(["$templateCache", function($templateCache) { $templateCache.put("hello.html", "<div><h1>Hi 我是林炳文~~~</h1></div>"); }]); </script> </html>結果:
其實第一種方法還好一些,寫起來會比較快,筆者就得最多的也是第一種寫法,直接包在scprit當中
6.replace
(布爾值),默認值為false,設置為true時候,我們再來看看下面的例子(對比下在template時候舉的例子)
replace為true時,hello-world這個標籤不在了,反之,則存在。
7.scope
(1)默認值false。表示繼承父作用域;
(2)true。表示繼承父作用域,並創建自己的作用域(子作用域);
(3){}。表示創建一個全新的隔離作用域;
7.1首先我們先來了解下scope的繼承機制。我們用ng-controller這個指令舉例,
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <div ng-controller='MainController'> 父親:{{name}}<input ng-model="name" /> <div my-directive></div> </div> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.controller('MainController', function ($scope) { $scope.name = '林炳文'; }); app.directive('myDirective', function () { return { restrict: 'EA', scope:false, template: '<div>兒子:{{ name }}<input ng-model="name"/></div>' }; }); </script> </html>接下來我們通過一個簡單明了的例子來說明scope取值不同的差別:
scope:false
scope:true
scope:{}
當為false時候,兒子繼承父親的值,改變父親的值,兒子的值也隨之變化,反之亦如此。 (繼承不隔離)
當為true時候,兒子繼承父親的值,改變父親的值,兒子的值隨之變化,但是改變兒子的值,父親的值不變。 (繼承隔離)
當為{}時候,沒有繼承父親的值,所以兒子的值為空,改變任何一方的值均不能影響另一方的值。 (不繼承隔離)
tip:當你想要創建一個可重用的組件時隔離作用域是一個很好的選擇,通過隔離作用域我們確保指令是'獨立'的,並可以輕鬆地插入到任何HTML app中,並且這種做法防止了父作用域被污染;
7.2隔離作用域可以通過綁定策略來訪問父作用域的屬性。
directive 在使用隔離scope 的時候,提供了三種方法同隔離之外的地方交互。這三種分別是
@ 綁定一個局部scope 屬性到當前dom 節點的屬性值。結果總是一個字符串,因為dom 屬性是字符串。
& 提供一種方式執行一個表達式在父scope 的上下文中。如果沒有指定attr 名稱,則屬性名稱為相同的本地名稱。
= 通過directive 的attr 屬性的值在局部scope 的屬性和父scope 屬性名之間建立雙向綁定。
@ 局部scope 屬性
@ 方式局部屬性用來訪問directive 外部環境定義的字符串值,主要是通過directive 所在的標籤屬性綁定外部字符串值。這種綁定是單向的,即父scope 的綁定變化,directive 中的scope 的屬性會同步變化,而隔離scope 中的綁定變化,父scope 是不知道的。
如下示例:directive 聲明未隔離scope 類型,並且使用@綁定name 屬性,在directive 中使用name 屬性綁定父scope 中的屬性。當改變父scope 中屬性的值的時候,directive 會同步更新值,當改變directive 的scope 的屬性值時,父scope 無法同步更新值。
js 代碼:
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <div ng-controller="myController"> <div> <div>父scope: <div>Say:{{name}}<br>改變父scope的name:<input type="text" value="" ng-model="name"/></div> </div> <div>隔離scope: <div isolated-directive name="{{name}}"></div> </div> <div>隔離scope(不使用父scope {{name}}): <div isolated-directive name="name"></div> </div> </div> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.controller("myController", function ($scope) { $scope.name = "hello world"; }).directive("isolatedDirective", function () { return { scope: { name: "@" }, template: 'Say:{{name}} <br>改變隔離scope的name:<input type="buttom" value="" ng-model="name">' }; }); </script> </html>結果:頁面初始效果
動畫效果:
可以看到父scope上的內容髮生改變,子scope同時發生改變。而子scope上的內容髮生改變。不影響父scope上的內容!
= 局部scope 屬性
= 通過directive 的attr 屬性的值在局部scope 的屬性和父scope 屬性名之間建立雙向綁定。
意思是,當你想要一個雙向綁定的屬性的時候,你可以使用=來引入外部屬性。無論是改變父scope 還是隔離scope 裡的屬性,父scope 和隔離scope 都會同時更新屬性值,因為它們是雙向綁定的關係。
示例代碼:
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <div ng-controller="myController"> <div>父scope: <div>Say:{{user.name}}<br>改變父scope的name:<input type="text" value="" ng-model="userBase.name"/></div> </div> <div>隔離scope: <div isolated-directive user="userBase"></div> </div> </div> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.controller("myController", function ($scope) { $scope.userBase = { name: 'hello', id: 1 }; }).directive("isolatedDirective", function () { return { scope: { user: "=" }, template: 'Say:{{user.name}} <br>改變隔離scope的name:<input type="buttom" value="" ng-model="user.name"/>' } }) </script> </html>效果:
可以看到父scope和子scope上的內容一直都是一樣的!
& 局部scope 屬性
& 方式提供一種途經是directive 能在父scope 的上下文中執行一個表達式。此表達式可以是一個function。
比如當你寫了一個directive,當用戶點擊按鈕時,directive 想要通知controller,controller 無法知道directive 中發生了什麼,也許你可以通過使用angular 中的event 廣播來做到,但是必須要在controller 中增加一個事件監聽方法。
最好的方法就是讓directive 可以通過一個父scope 中的function,當directive 中有什麼動作需要更新到父scope 中的時候,可以在父scope 上下文中執行一段代碼或者一個函數。
如下示例在directive 中執行父scope 的function。
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <body> <div ng-controller="myController"> <div>父scope: <div>Say:{{value}}</div> </div> <div>隔離scope: <div isolated-directive action="click()"></div> </div> </div> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.controller("myController", function ($scope) { $scope.value = "hello world"; $scope.click = function () { $scope.value = Math.random(); }; }).directive("isolatedDirective", function () { return { scope: { action: "&" }, template: '<input type="button" value="在directive中執行父scope定義的方法" ng-click="action()"/>' } }) </script> </html>效果:
指令的內容比較多,下面再來講講transclude、compline、link、contrller
8.transclude
如果不想讓指令內部的內容被模板替換,可以設置這個值為true。一般情況下需要和ngTransclude指令一起使用。 比如:template:"<div>hello every <div ng-transclude></div></div>",這時,指令內部的內容會嵌入到ng-transclude這個div中。也就是變成了<div>hello every <div>這是指令內部的內容</div></div>。默認值為false;這個配置選項可以讓我們提取包含在指令那個元素裡面的內容,再將它放置在指令模板的特定位置。當你開啟transclude後,你就可以使用ng-transclude來指明了應該在什麼地方放置transcluded內容
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <div sidebox> <ul> <li>First link</li> <li>Second link</li> </ul> </div> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.directive('sidebox', function() { return { restrict: 'EA', scope: { title: '@' }, transclude: true, template: '<div>/ <div>/ <h2>{{ title }}</h2>/ <span ng-transclude>/ </span>/ </div>/ </div>' }; }); </script> </html>結果:
當transclude: false,時
如果指令使用了transclude參數,那麼在控制器無法正常監聽數據模型的變化了。建議在鏈接函數里使用$watch服務。
9.controller
可以是一個字符串或者函數。
若是為字符串,則將字符串當做是控制器的名字,來查找註冊在應用中的控制器的構造函數
angular.module('myApp', []) .directive('myDirective', function() { restrict: 'A', // 始終需要controller: 'SomeController' }) // 應用中其他的地方,可以是同一個文件或被index.html包含的另一個文件angular.module('myApp') .controller('SomeController', function($scope, $element, $attrs, $transclude) { // 控制器邏輯放在這裡}); 也可以直接在指令內部的定義為匿名函數,同樣我們可以再這裡註入任何服務($log,$timeout等等)[html] view plain copy 在CODE上查看代碼片派生到我的代碼片angular.module('myApp',[]) .directive('myDirective', function() { restrict: 'A', controller: function($scope, $element, $attrs, $transclude) { // 控制器邏輯放在這裡} });另外還有一些特殊的服務(參數)可以注入
(1)$scope,與指令元素相關聯的作用域
(2)$element,當前指令對應的元素
(3)$attrs,由當前元素的屬性組成的對象
(4)$transclude,嵌入鏈接函數,實際被執行用來克隆元素和操作DOM的函數
注意:除非是用來定義一些可複用的行為,一般不推薦在這使用。
指令的控制器和link函數(後面會講)可以進行互換。區別在於,控制器主要是用來提供可在指令間復用的行為但link鏈接函數只能在當前內部指令中定義行為,且無法再指令間復用。
<!DOCTYPE html> <html lang="zh" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS入門學習</title> <script type="text/javascript" src="./1.5.3/angular.min.js"></script> </head> <hello mycolor ="red">我是林炳文~~~</hello> </body> <script type="text/javascript"> var app = angular.module('myApp', []); app.directive('hello', function() { return { restrict: 'EA', transclude: true, //注意此處必須設置為true controller: function ($scope, $element,$attrs,$transclude,$log) { //在這裡你可以注入你想注入的服務$transclude(function (clone) { var a = angular.element('<p>'); a.css('color', $attrs.mycolor); a.text(clone.text()); $element.append(a); }); $log.info("hello everyone"); } }; }); </script> </html>輸出結果:
並且在控制台下輸出hello everyone
讓我們看看$transclude();在這裡,它可以接收兩個參數,第一個是$scope,作用域,第二個是帶有參數clone的回調函數。而這個clone實際上就是嵌入的內容(經過jquery包裝),可以在它上做很多DOM操作。
它還有最簡單的用法就是
<script> angular.module('myApp',[]).directive('mySite', function () { return { restrict: 'EA', transclude: true, controller: function ($scope, $element,$attrs,$transclude,$log) { var a = $transclude(); //$transclude()就是嵌入的內容$element.append(a); } }; }); </script>注意:使用$transclude會生成一個新的作用域。
默認情況下,如果我們簡單實用$transclude(),那麼默認的其作用域就是$transclude生成的作用域
但是如果我們實用$transclude($scope,function(clone){}),那麼作用域就是directive的作用域了
那麼問題又來了。如果我們想實用父作用域呢
可以使用$scope.$parent
同理想要一個新的作用域也可以使用$scope.$parent.new();
10.controllerAs
這個選項的作用是可以設置你的控制器的別名
一般以前我們經常用這樣方式來寫代碼:
angular.module("app",[]) .controller("demoController",["$scope",function($scope){ $scope.title = "angualr"; }]) <div ng-app="app" ng-controller="demoController"> {{title}} </div>後來angularjs1.2給我們帶來新語法糖,所以我們可以這樣寫
angular.module("app",[]) .controller("demoController",[function(){ this.title = "angualr"; }]) <div ng-app="app" ng-controller="demoController as demo"> {{demo.title}} </div>同樣的我們也可以再指令裡面也這樣寫
<script> angular.module('myApp',[]).directive('mySite', function () { return { restrict: 'EA', transclude: true, controller:'someController', controllerAs:'mainController' //..其他配置}; }); </script>11.require(字符串或者數組)
字符串代表另一個指令的名字,它將會作為link函數的第四個參數。具體用法我們可以舉個例子說明。假設現在我們要編寫兩個指令,兩個指令中的link鏈接函數中(link函數後面會講)存在有很多重合的方法,這時候我們就可以將這些重複的方法寫在第三個指令的controller中(上面也講到controller經常用來提供指令間的複用行為)然後在這兩個指令中,require這個擁有controller字段的的指令(第三個指令),
最後通過link鏈接函數的第四個參數就可以引用這些重合的方法了。
<!doctype html> <html ng-app="myApp"> <head> <script src="http://cdn.staticfile.org/angular.js/1.2.10/angular.min.js"></script> </head> <body> <outer-directive> <inner-directive></inner-directive> <inner-directive2></inner-directive2> </outer-directive> <script> var app = angular.module('myApp', []); app.directive('outerDirective', function() { return { scope: {}, restrict: 'AE', controller: function($scope) { this.say = function(someDirective) { console.log('Got:' + someDirective.message); }; } }; }); app.directive('innerDirective', function() { return { scope: {}, restrict: 'AE', require: '^outerDirective', link: function(scope, elem, attrs, controllerInstance) { scope.message = "Hi,leifeng"; controllerInstance.say(scope); } }; }); app.directive('innerDirective2', function() { return { scope: {}, restrict: 'AE', require: '^outerDirective', link: function(scope, elem, attrs, controllerInstance) { scope.message = "Hi,shushu"; controllerInstance.say(scope); } }; }); </script> </body> </html>上面例子中的指令innerDirective和指令innerDirective2復用了定義在指令outerDirective的controller中的方法
也進一步說明了,指令中的controller是用來讓不同指令間通信用的。
另外我們可以在require的參數值加上下面的某個前綴,這會改變查找控制器的行為:
(1)沒有前綴,指令會在自身提供的控制器中進行查找,如果找不到任何控制器,則會拋出一個error
(2)?如果在當前的指令沒有找到所需的控制器,則會將null傳給link連接函數的第四個參數
(3)^如果在當前的指令沒有找到所需的控制器,則會查找父元素的控制器
(4)?^組合
12.Anguar的指令編譯過程
首先加載angularjs庫,查找到ng-app指令,從而找到應用的邊界,
根據ng-app劃定的作用域來調用$compile服務進行編譯,angularjs會遍歷整個HTML文檔,並根據js中指令的定義來處理在頁面上聲明的各個指令按照指令的優先級(priority)排列,根據指令中的配置參數(template,place,transclude等)轉換DOM然後就開始按順序執行各指令的compile函數(如果指令上有定義compile函數)對模板自身進行轉換
注意:此處的compile函數是我們指令中配置的,跟上面說的$compile服務不一樣。每個compile函數執行完後都會返回一個link函數,所有的link函數會合成一個大的link函數
然後這個大的link函數就會被執行,主要做數據綁定,通過在DOM上註冊監聽器來動態修改scope中的數據,或者是使用$watchs監聽scope中的變量來修改DOM,從而建立雙向綁定等等。若我們的指令中沒有配置compile函數,那我們配置的link函數就會運行,她做的事情大致跟上面complie返回之後所有的link函數合成的的大的link函數差不多。
所以:在指令中compile與link選項是互斥的,如果同時設置了這兩個選項,那麼就會把compile所返回的函數當做是鏈接函數,而link選項本身就會被忽略掉
13、編譯函數Compile function
function compile(tElement, tAttrs, transclude) { ... }
編譯函數是用來處理需要修改模板DOM的情況的。因為大部分指令都不需要修改模板,所以這個函數也不常用。需要用到的例子有ngTrepeat,這個是需要修改模板的,還有ngView這個是需要異步載入內容的。編譯函數接受以下參數。
tElement - template element - 指令所在的元素。對這個元素及其子元素進行變形之類的操作是安全的。
tAttrs - template attributes - 這個元素上所有指令聲明的屬性,這些屬性都是在編譯函數里共享的。
transclude - 一個嵌入的鏈接函數function(scope, cloneLinkingFn)。
注意:在編譯函數里面不要進行任何DOM變形之外的操作。 更重要的,DOM監聽事件的註冊應該在鏈接函數中做,而不是編譯函數中。
編譯函數可以返回一個對像或者函數。
返回函數- 等效於在編譯函數不存在時,使用配置對象的link屬性註冊的鏈接函數。
返回對象- 返回一個通過pre或post屬性註冊了函數的對象。參考下面pre-linking和post-liking函數的解釋。
14、鏈接函數Linking function
function link(scope, iElement, iAttrs, controller) { ... }
鏈接函數負責註冊DOM事件和更新DOM。它是在模板被克隆之後執行的,它也是大部分指令邏輯代碼編寫的地方。
scope - 指令需要監聽的作用域。
iElement - instance element - 指令所在的元素。只有在postLink函數中對元素的子元素進行操作才是安全的,因為那時它們才已經全部鏈接好。
iAttrs - instance attributes - 實例屬性,一個標準化的、所有聲明在當前元素上的屬性列表,這些屬性在所有鏈接函數間是共享的。
controller - 控制器實例,也就是當前指令通過require請求的指令direct2內部的controller。比如:direct2指令中的controller:function(){this.addStrength = function(){}},那麼,在當前指令的link函數中,你就可以通過controller.addStrength進行調用了。
Pre-linking function 在子元素被鏈接前執行。不能用來進行DOM的變形,以防鏈接函數找不到正確的元素來鏈接。
Post-linking function 所有元素都被鏈接後執行。
說明:
compile選項本身並不會被頻繁使用,但是link函數則會被經常使用。本質上,當我們設置了link選項,實際上是創建了一個postLink() 鏈接函數,以便compile() 函數可以定義鏈接函數。通常情況下,如果設置了compile函數,說明我們希望在指令和實時數據被放到DOM中之前進行DOM操作,在這個函數中進行諸如添加和刪除節點等DOM操作是安全的。 compile和link選項是互斥的。如果同時設置了這兩個選項,那麼會把compile所返回的函數當作鏈接函數,而link選項本身則會被忽略。譯函數負責對模板DOM進行轉換。鏈接函數負責將作用域和DOM進行鏈接。 在作用域同DOM鏈接之前可以手動操作DOM。在實踐中,編寫自定義指令時這種操作是非常罕見的,但有幾個內置指令提供了這樣的功能。 鏈接函數是可選的。如果定義了編譯函數,它會返回鏈接函數,因此當兩個函數都定義時,編譯函數會重載鏈接函數。如果我們的指令很簡單,並且不需要額外的設置,可以從工廠函數(回調函數)返回一個函數來代替對象。如果這樣做了,這個函數就是鏈接函數。
本文轉載http://blog.csdn.net/evankaka
以上就是AngularJs:Directive指令用法的全部內容,希望對大家的學習有所幫助。