欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

學(xué)習(xí)AngularJs:Directive指令用法(完整版)

 更新時(shí)間:2016年04月26日 10:57:27   作者:林炳文Evankaka  
這篇文章主要學(xué)習(xí)AngularJs:Directive指令用法,內(nèi)容很全面,感興趣的小伙伴們可以參考一下

本教程使用AngularJs版本:1.5.3

AngularJs GitHub: https://github.com/angular/angular.js/

AngularJs下載地址:https://angularjs.org/

摘要:Directive(指令)筆者認(rèn)為是AngularJ非常強(qiáng)大而有有用的功能之一。它就相當(dāng)于為我們寫了公共的自定義DOM元素或CLASS屬性或ATTR屬性,并且它不只是單單如此,你還可以在它的基礎(chǔ)上來(lái)操作scope、綁定事件、更改樣式等。通過(guò)這個(gè)Directive,我們可以封裝很多公共指令,比如分頁(yè)指令、自動(dòng)補(bǔ)全指令等等。然后在HTML頁(yè)面里只需要簡(jiǎn)單的寫一行代碼就可以實(shí)現(xiàn)很多強(qiáng)大的功能。一般情況下,需要用Directive有下面的情景:
1. 使你的Html更具語(yǔ)義化,不需要深入研究代碼和邏輯即可知道頁(yè)面的大致邏輯。
2. 抽象一個(gè)自定義組件,在其他地方進(jìn)行重用。

一、Directive的定義及其使用方法
AngularJs的指令定義大致如下

angular.module("app",[]).directive("directiveName",function(){ 
 return{ 
 //通過(guò)設(shè)置項(xiàng)來(lái)定義 
 }; 
}) 

Directive可以放置于元素名、屬性、class、注釋中。下面是引用myDir這個(gè)directive的等價(jià)方式。(但很多directive都限制為“屬性”的使用方式)

<span <span style="font-family: Arial, Helvetica, sans-serif;">directive-name</span><span style="font-family: Arial, Helvetica, sans-serif;">="exp"></span>//屬性</span> 
 
<span class="<span style="font-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> 

如下一個(gè)實(shí)例 :

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</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> 

結(jié)果:


下面是一個(gè)directive的詳細(xì)版

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指令內(nèi)容解讀
可 以看到它有8個(gè)內(nèi)容
1.restrict
(字符串)可選參數(shù),指明指令在DOM里面以什么形式被聲明;取值有:E(元素),A(屬性),C(類),M(注釋),其中默認(rèn)值為A;當(dāng)然也可以兩個(gè)一起用,比如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
(數(shù)字),可選參數(shù),指明指令的優(yōu)先級(jí),若在單個(gè)DOM上有多個(gè)指令,則優(yōu)先級(jí)高的先執(zhí)行;

3.terminal
(布爾型),可選參數(shù),可以被設(shè)置為true或false,若設(shè)置為true,則優(yōu)先級(jí)低于此指令的其他指令則無(wú)效,不會(huì)被調(diào)用(優(yōu)先級(jí)相同的還是會(huì)執(zhí)行)

4.template(字符串或者函數(shù))可選參數(shù),可以是:
(1)一段HTML文本

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</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)一個(gè)函數(shù),可接受兩個(gè)參數(shù)tElement和tAttrs
其中tElement是指使用此指令的元素,而tAttrs則實(shí)例的屬性,它是一個(gè)由元素上所有的屬性組成的集合(對(duì)象)形如:
<hello-world2 title = '我是第二個(gè)directive'></hello-world2> 
其中title就是tattrs上的屬性

下面讓我們看看template是一個(gè)函數(shù)時(shí)候的情況

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
<hello-world></hello-world> 
<hello-world2 title = '我是第二個(gè)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> 

結(jié)果:


可以看到指令中還用到了hello-world2中的標(biāo)簽中的 title字段

5.templateUrl(字符串或者函數(shù)),可選參數(shù),可以是
(1)一個(gè)代表HTML文件路徑的字符串

(2)一個(gè)函數(shù),可接受兩個(gè)參數(shù)tElement和tAttrs(大致同上)

注意:在本地開(kāi)發(fā)時(shí)候,需要運(yùn)行一個(gè)服務(wù)器,不然使用templateUrl會(huì)報(bào)錯(cuò) Cross Origin Request Script(CORS)錯(cuò)誤。由于加載html模板是通過(guò)異步加載的,若加載大量的模板會(huì)拖慢網(wǎng)站的速度,這里有個(gè)技巧,就是先緩存模板
你可以再你的index頁(yè)面加載好的,將下列代碼作為你頁(yè)面的一部分包含在里面。

<script type='text/ng-template' id='hello.html'> 
 <div><h1>Hi 我是林炳文~~~</h1></div> 
</script> 

這里的id屬性就是被設(shè)置在templateUrl上用的。

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</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> 

輸出結(jié)果:


另一種辦法緩存是:

app.run(["$templateCache", function($templateCache) { 
 $templateCache.put("hello.html", 
 "<div><h1>Hi 我是林炳文~~~</h1></div>"); 
}]); 

使用實(shí)例如下:

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</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> 

結(jié)果:


 其實(shí)第一種方法還好一些,寫起來(lái)會(huì)比較快,筆者就得最多的也是第一種寫法,直接包在scprit當(dāng)中

 6.replace
(布爾值),默認(rèn)值為false,設(shè)置為true時(shí)候,我們?cè)賮?lái)看看下面的例子(對(duì)比下在template時(shí)候舉的例子)

                

 replace為true時(shí),hello-world這個(gè)標(biāo)簽不在了,反之,則存在。

7.scope
(1)默認(rèn)值false。表示繼承父作用域;

(2)true。表示繼承父作用域,并創(chuàng)建自己的作用域(子作用域);

(3){}。表示創(chuàng)建一個(gè)全新的隔離作用域;

7.1首先我們先來(lái)了解下scope的繼承機(jī)制。我們用ng-controller這個(gè)指令舉例,

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</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> 

接下來(lái)我們通過(guò)一個(gè)簡(jiǎn)單明了的例子來(lái)說(shuō)明scope取值不同的差別:

scope:false

scope:true

scope:{}

當(dāng)為false時(shí)候,兒子繼承父親的值,改變父親的值,兒子的值也隨之變化,反之亦如此。(繼承不隔離)

當(dāng)為true時(shí)候,兒子繼承父親的值,改變父親的值,兒子的值隨之變化,但是改變兒子的值,父親的值不變。(繼承隔離)

當(dāng)為{}時(shí)候,沒(méi)有繼承父親的值,所以兒子的值為空,改變?nèi)魏我环降闹稻荒苡绊懥硪环降闹?。(不繼承隔離)

tip:當(dāng)你想要?jiǎng)?chuàng)建一個(gè)可重用的組件時(shí)隔離作用域是一個(gè)很好的選擇,通過(guò)隔離作用域我們確保指令是‘獨(dú)立'的,并可以輕松地插入到任何HTML app中,并且這種做法防止了父作用域被污染;
7.2隔離作用域可以通過(guò)綁定策略來(lái)訪問(wèn)父作用域的屬性。
directive 在使用隔離 scope 的時(shí)候,提供了三種方法同隔離之外的地方交互。這三種分別是

@ 綁定一個(gè)局部 scope 屬性到當(dāng)前 dom 節(jié)點(diǎn)的屬性值。結(jié)果總是一個(gè)字符串,因?yàn)?dom 屬性是字符串。
& 提供一種方式執(zhí)行一個(gè)表達(dá)式在父 scope 的上下文中。如果沒(méi)有指定 attr 名稱,則屬性名稱為相同的本地名稱。
= 通過(guò) directive 的 attr 屬性的值在局部 scope 的屬性和父 scope 屬性名之間建立雙向綁定。

@ 局部 scope 屬性

@ 方式局部屬性用來(lái)訪問(wèn) directive 外部環(huán)境定義的字符串值,主要是通過(guò) directive 所在的標(biāo)簽屬性綁定外部字符串值。這種綁定是單向的,即父 scope 的綁定變化,directive 中的 scope 的屬性會(huì)同步變化,而隔離 scope 中的綁定變化,父 scope 是不知道的。

如下示例:directive 聲明未隔離 scope 類型,并且使用@綁定 name 屬性,在 directive 中使用 name 屬性綁定父 scope 中的屬性。當(dāng)改變父 scope 中屬性的值的時(shí)候,directive 會(huì)同步更新值,當(dāng)改變 directive 的 scope 的屬性值時(shí),父 scope 無(wú)法同步更新值。

js 代碼:

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<body> 
<div ng-controller="myController"> 
 <div class="result"> 
 <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" class="ng-pristine ng-valid">' 
 }; 
}); 
</script> 
</html> 

結(jié)果:頁(yè)面初始效果

動(dòng)畫效果:


可以看到父scope上的內(nèi)容發(fā)生改變,子scope同時(shí)發(fā)生改變。而子scope上的內(nèi)容發(fā)生改變。不影響父scope上的內(nèi)容!

= 局部 scope 屬性

= 通過(guò) directive 的 attr 屬性的值在局部 scope 的屬性和父 scope 屬性名之間建立雙向綁定。
意思是,當(dāng)你想要一個(gè)雙向綁定的屬性的時(shí)候,你可以使用=來(lái)引入外部屬性。無(wú)論是改變父 scope 還是隔離 scope 里的屬性,父 scope 和隔離 scope 都會(huì)同時(shí)更新屬性值,因?yàn)樗鼈兪请p向綁定的關(guān)系。

示例代碼:

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</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上的內(nèi)容一直都是一樣的!
& 局部 scope 屬性

& 方式提供一種途經(jīng)是 directive 能在父 scope 的上下文中執(zhí)行一個(gè)表達(dá)式。此表達(dá)式可以是一個(gè) function。
比如當(dāng)你寫了一個(gè) directive,當(dāng)用戶點(diǎn)擊按鈕時(shí),directive 想要通知 controller,controller 無(wú)法知道 directive 中發(fā)生了什么,也許你可以通過(guò)使用 angular 中的 event 廣播來(lái)做到,但是必須要在 controller 中增加一個(gè)事件監(jiān)聽(tīng)方法。
最好的方法就是讓 directive 可以通過(guò)一個(gè)父 scope 中的 function,當(dāng) directive 中有什么動(dòng)作需要更新到父 scope 中的時(shí)候,可以在父 scope 上下文中執(zhí)行一段代碼或者一個(gè)函數(shù)。

如下示例在 directive 中執(zhí)行父 scope 的 function。

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</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中執(zhí)行父scope定義的方法" ng-click="action()"/>' 
 } 
 }) 
</script> 
</html> 

效果:


指令的內(nèi)容比較多,下面再來(lái)講講transclude、compline、link、contrller

8.transclude
 如果不想讓指令內(nèi)部的內(nèi)容被模板替換,可以設(shè)置這個(gè)值為true。一般情況下需要和ngTransclude指令一起使用。 比如:template:"<div>hello every <div ng-transclude></div></div>",這時(shí),指令內(nèi)部的內(nèi)容會(huì)嵌入到ng-transclude這個(gè)div中。也就是變成了<div>hello every <div>這是指令內(nèi)部的內(nèi)容</div></div>。默認(rèn)值為false;這個(gè)配置選項(xiàng)可以讓我們提取包含在指令那個(gè)元素里面的內(nèi)容,再將它放置在指令模板的特定位置。當(dāng)你開(kāi)啟transclude后,你就可以使用ng-transclude來(lái)指明了應(yīng)該在什么地方放置transcluded內(nèi)容

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</title> 
 <script type="text/javascript" src="./1.5.3/angular.min.js"></script> 
</head> 
<div sidebox title="Links"> 
  <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 class="sidebox">\ 
  <div class="content">\ 
  <h2 class="header">{{ title }}</h2>\ 
  <span class="content" ng-transclude>\ 
  </span>\ 
  </div>\ 
 </div>' 
 }; 
}); 
</script> 
</html> 

結(jié)果:

當(dāng)  transclude: false,時(shí)

如果指令使用了transclude參數(shù),那么在控制器無(wú)法正常監(jiān)聽(tīng)數(shù)據(jù)模型的變化了。建議在鏈接函數(shù)里使用$watch服務(wù)。
9.controller
可以是一個(gè)字符串或者函數(shù)。

若是為字符串,則將字符串當(dāng)做是控制器的名字,來(lái)查找注冊(cè)在應(yīng)用中的控制器的構(gòu)造函數(shù)

angular.module('myApp', []) 
.directive('myDirective', function() { 
restrict: 'A', // 始終需要 
controller: 'SomeController' 
}) 
// 應(yīng)用中其他的地方,可以是同一個(gè)文件或被index.html包含的另一個(gè)文件 
angular.module('myApp') 
.controller('SomeController', function($scope, $element, $attrs, $transclude) { 
// 控制器邏輯放在這里 
}); 
也可以直接在指令內(nèi)部的定義為匿名函數(shù),同樣我們可以再這里注入任何服務(wù)($log,$timeout等等)

[html] view plain copy 在CODE上查看代碼片派生到我的代碼片
angular.module('myApp',[]) 
.directive('myDirective', function() { 
restrict: 'A', 
controller: 
function($scope, $element, $attrs, $transclude) { 
// 控制器邏輯放在這里 
} 
}); 

另外還有一些特殊的服務(wù)(參數(shù))可以注入

(1)$scope,與指令元素相關(guān)聯(lián)的作用域

(2)$element,當(dāng)前指令對(duì)應(yīng)的 元素

(3)$attrs,由當(dāng)前元素的屬性組成的對(duì)象

(4)$transclude,嵌入鏈接函數(shù),實(shí)際被執(zhí)行用來(lái)克隆元素和操作DOM的函數(shù)

注意: 除非是用來(lái)定義一些可復(fù)用的行為,一般不推薦在這使用。
         指令的控制器和link函數(shù)(后面會(huì)講)可以進(jìn)行互換。區(qū)別在于,控制器主要是用來(lái)提供可在指令間復(fù)用的行為但link鏈接函數(shù)只能在當(dāng)前內(nèi)部指令中定義行為,且無(wú)法再指令間復(fù)用。

<!DOCTYPE html> 
<html lang="zh" ng-app="myApp"> 
<head> 
 <meta charset="UTF-8"> 
 <title>AngularJS入門學(xué)習(xí)</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, //注意此處必須設(shè)置為true 
  controller: 
  function ($scope, $element,$attrs,$transclude,$log) { //在這里你可以注入你想注入的服務(wù) 
  $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> 

輸出結(jié)果:


并且在控制臺(tái)下輸出hello everyone

讓我們看看$transclude();在這里,它可以接收兩個(gè)參數(shù),第一個(gè)是$scope,作用域,第二個(gè)是帶有參數(shù)clone的回調(diào)函數(shù)。而這個(gè)clone實(shí)際上就是嵌入的內(nèi)容(經(jīng)過(guò)jquery包裝),可以在它上做很多DOM操作。

它還有最簡(jiǎn)單的用法就是

<script> 
 angular.module('myApp',[]).directive('mySite', function () { 
 return { 
  restrict: 'EA', 
  transclude: true, 
  controller: 
  function ($scope, $element,$attrs,$transclude,$log) { 
  var a = $transclude(); //$transclude()就是嵌入的內(nèi)容 
  $element.append(a); 
  } 
 }; 
 }); 
 </script> 

注意:使用$transclude會(huì)生成一個(gè)新的作用域。
默認(rèn)情況下,如果我們簡(jiǎn)單實(shí)用$transclude(),那么默認(rèn)的其作用域就是$transclude生成的作用域

但是如果我們實(shí)用$transclude($scope,function(clone){}),那么作用域就是directive的作用域了

那么問(wèn)題又來(lái)了。如果我們想實(shí)用父作用域呢

可以使用$scope.$parent

同理想要一個(gè)新的作用域也可以使用$scope.$parent.new();
10.controllerAs
這個(gè)選項(xiàng)的作用是可以設(shè)置你的控制器的別名

一般以前我們經(jīng)常用這樣方式來(lái)寫代碼:

angular.module("app",[]) 
 .controller("demoController",["$scope",function($scope){ 
 $scope.title = "angualr"; 
 }]) 
 
 <div ng-app="app" ng-controller="demoController"> 
 {{title}} 
</div> 

后來(lái)angularjs1.2給我們帶來(lái)新語(yǔ)法糖,所以我們可以這樣寫

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(字符串或者數(shù)組)
字符串代表另一個(gè)指令的名字,它將會(huì)作為link函數(shù)的第四個(gè)參數(shù)。具體用法我們可以舉個(gè)例子說(shuō)明。假設(shè)現(xiàn)在我們要編寫兩個(gè)指令,兩個(gè)指令中的link鏈接函數(shù)中(link函數(shù)后面會(huì)講)存在有很多重合的方法,這時(shí)候我們就可以將這些重復(fù)的方法寫在第三個(gè)指令的controller中(上面也講到controller經(jīng)常用來(lái)提供指令間的復(fù)用行為)然后在這兩個(gè)指令中,require這個(gè)擁有controller字段的的指令(第三個(gè)指令),

最后通過(guò)link鏈接函數(shù)的第四個(gè)參數(shù)就可以引用這些重合的方法了。

<!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復(fù)用了定義在指令outerDirective的controller中的方法

也進(jìn)一步說(shuō)明了,指令中的controller是用來(lái)讓不同指令間通信用的。

另外我們可以在require的參數(shù)值加上下面的某個(gè)前綴,這會(huì)改變查找控制器的行為:

(1)沒(méi)有前綴,指令會(huì)在自身提供的控制器中進(jìn)行查找,如果找不到任何控制器,則會(huì)拋出一個(gè)error

(2)?如果在當(dāng)前的指令沒(méi)有找到所需的控制器,則會(huì)將null傳給link連接函數(shù)的第四個(gè)參數(shù)

(3)^如果在當(dāng)前的指令沒(méi)有找到所需的控制器,則會(huì)查找父元素的控制器

(4)?^組合

12.Anguar的指令編譯過(guò)程
首先加載angularjs庫(kù),查找到ng-app指令,從而找到應(yīng)用的邊界,

根據(jù)ng-app劃定的作用域來(lái)調(diào)用$compile服務(wù)進(jìn)行編譯,angularjs會(huì)遍歷整個(gè)HTML文檔,并根據(jù)js中指令的定義來(lái)處理在頁(yè)面上聲明的各個(gè)指令按照指令的優(yōu)先級(jí)(priority)排列,根據(jù)指令中的配置參數(shù)(template,place,transclude等)轉(zhuǎn)換DOM然后就開(kāi)始按順序執(zhí)行各指令的compile函數(shù)(如果指令上有定義compile函數(shù))對(duì)模板自身進(jìn)行轉(zhuǎn)換

注意:此處的compile函數(shù)是我們指令中配置的,跟上面說(shuō)的$compile服務(wù)不一樣。每個(gè)compile函數(shù)執(zhí)行完后都會(huì)返回一個(gè)link函數(shù),所有的link函數(shù)會(huì)合成一個(gè)大的link函數(shù)

然后這個(gè)大的link函數(shù)就會(huì)被執(zhí)行,主要做數(shù)據(jù)綁定,通過(guò)在DOM上注冊(cè)監(jiān)聽(tīng)器來(lái)動(dòng)態(tài)修改scope中的數(shù)據(jù),或者是使用$watchs監(jiān)聽(tīng) scope中的變量來(lái)修改DOM,從而建立雙向綁定等等。若我們的指令中沒(méi)有配置compile函數(shù),那我們配置的link函數(shù)就會(huì)運(yùn)行,她做的事情大致跟上面complie返回之后所有的link函數(shù)合成的的大的link函數(shù)差不多。

所以:在指令中compile與link選項(xiàng)是互斥的,如果同時(shí)設(shè)置了這兩個(gè)選項(xiàng),那么就會(huì)把compile所返回的函數(shù)當(dāng)做是鏈接函數(shù),而link選項(xiàng)本身就會(huì)被忽略掉

13、編譯函數(shù) Compile function

function compile(tElement, tAttrs, transclude) { ... }
編譯函數(shù)是用來(lái)處理需要修改模板DOM的情況的。因?yàn)榇蟛糠种噶疃疾恍枰薷哪0?,所以這個(gè)函數(shù)也不常用。需要用到的例子有ngTrepeat,這個(gè)是需要修改模板的,還有ngView這個(gè)是需要異步載入內(nèi)容的。編譯函數(shù)接受以下參數(shù)。

tElement - template element - 指令所在的元素。對(duì)這個(gè)元素及其子元素進(jìn)行變形之類的操作是安全的。
tAttrs - template attributes - 這個(gè)元素上所有指令聲明的屬性,這些屬性都是在編譯函數(shù)里共享的。
transclude - 一個(gè)嵌入的鏈接函數(shù)function(scope, cloneLinkingFn)。
注意:在編譯函數(shù)里面不要進(jìn)行任何DOM變形之外的操作。 更重要的,DOM監(jiān)聽(tīng)事件的注冊(cè)應(yīng)該在鏈接函數(shù)中做,而不是編譯函數(shù)中。
編譯函數(shù)可以返回一個(gè)對(duì)象或者函數(shù)。
返回函數(shù) - 等效于在編譯函數(shù)不存在時(shí),使用配置對(duì)象的link屬性注冊(cè)的鏈接函數(shù)。
返回對(duì)象 - 返回一個(gè)通過(guò)pre或post屬性注冊(cè)了函數(shù)的對(duì)象。參考下面pre-linking和post-liking函數(shù)的解釋。

14、鏈接函數(shù) Linking function

function link(scope, iElement, iAttrs, controller) { ... }
鏈接函數(shù)負(fù)責(zé)注冊(cè)DOM事件和更新DOM。它是在模板被克隆之后執(zhí)行的,它也是大部分指令邏輯代碼編寫的地方。
scope - 指令需要監(jiān)聽(tīng)的作用域。
iElement - instance element - 指令所在的元素。只有在postLink函數(shù)中對(duì)元素的子元素進(jìn)行操作才是安全的,因?yàn)槟菚r(shí)它們才已經(jīng)全部鏈接好。
iAttrs - instance attributes - 實(shí)例屬性,一個(gè)標(biāo)準(zhǔn)化的、所有聲明在當(dāng)前元素上的屬性列表,這些屬性在所有鏈接函數(shù)間是共享的。
controller - 控制器實(shí)例,也就是當(dāng)前指令通過(guò)require請(qǐng)求的指令direct2內(nèi)部的controller。比如:direct2指令中的controller:function(){this.addStrength = function(){}},那么,在當(dāng)前指令的link函數(shù)中,你就可以通過(guò)controller.addStrength進(jìn)行調(diào)用了。
Pre-linking function 在子元素被鏈接前執(zhí)行。不能用來(lái)進(jìn)行DOM的變形,以防鏈接函數(shù)找不到正確的元素來(lái)鏈接。
Post-linking function 所有元素都被鏈接后執(zhí)行。

說(shuō)明:

    compile選項(xiàng)本身并不會(huì)被頻繁使用,但是link函數(shù)則會(huì)被經(jīng)常使用。本質(zhì)上,當(dāng)我們?cè)O(shè)置了link選項(xiàng),實(shí)際上是創(chuàng)建了一個(gè)postLink() 鏈接函數(shù),以便compile() 函數(shù)可以定義鏈接函數(shù)。通常情況下,如果設(shè)置了compile函數(shù),說(shuō)明我們希望在指令和實(shí)時(shí)數(shù)據(jù)被放到DOM中之前進(jìn)行DOM操作,在這個(gè)函數(shù)中進(jìn)行諸如添加和刪除節(jié)點(diǎn)等DOM操作是安全的。compile和link選項(xiàng)是互斥的。如果同時(shí)設(shè)置了這兩個(gè)選項(xiàng),那么會(huì)把compile所返回的函數(shù)當(dāng)作鏈接函數(shù),而link選項(xiàng)本身則會(huì)被忽略。譯函數(shù)負(fù)責(zé)對(duì)模板DOM進(jìn)行轉(zhuǎn)換。鏈接函數(shù)負(fù)責(zé)將作用域和DOM進(jìn)行鏈接。 在作用域同DOM鏈接之前可以手動(dòng)操作DOM。在實(shí)踐中,編寫自定義指令時(shí)這種操作是非常罕見(jiàn)的,但有幾個(gè)內(nèi)置指令提供了這樣的功能。 鏈接函數(shù)是可選的。如果定義了編譯函數(shù),它會(huì)返回鏈接函數(shù),因此當(dāng)兩個(gè)函數(shù)都定義時(shí),編譯函數(shù)會(huì)重載鏈接函數(shù)。如果我們的指令很簡(jiǎn)單,并且不需要額外的設(shè)置,可以從工廠函數(shù)(回調(diào)函數(shù))返回一個(gè)函數(shù)來(lái)代替對(duì)象。如果這樣做了,這個(gè)函數(shù)就是鏈接函數(shù)。

本文轉(zhuǎn)載http://blog.csdn.net/evankaka

以上就是AngularJs:Directive指令用法的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • 詳解如何在Angular中使用環(huán)境變量

    詳解如何在Angular中使用環(huán)境變量

    如果你正在構(gòu)建一個(gè)使用 API 的應(yīng)用程序,你會(huì)想在開(kāi)發(fā)過(guò)程中使用測(cè)試環(huán)境的 API 密鑰,而在生產(chǎn)環(huán)境中使用生產(chǎn)環(huán)境的 API 密鑰,在本教程中,你將學(xué)習(xí)如何在 Angular 中使用環(huán)境變量,需要的朋友可以參考下
    2024-02-02
  • 使用AngularJS創(chuàng)建自定義的過(guò)濾器的方法

    使用AngularJS創(chuàng)建自定義的過(guò)濾器的方法

    這篇文章主要介紹了使用AngularJS創(chuàng)建自定義的過(guò)濾器的方法,AngularJS是非常熱門的JavaScript庫(kù),需要的朋友可以參考下
    2015-06-06
  • 利用Ionic2 + angular4實(shí)現(xiàn)一個(gè)地區(qū)選擇組件

    利用Ionic2 + angular4實(shí)現(xiàn)一個(gè)地區(qū)選擇組件

    ionic是一個(gè)移動(dòng)端開(kāi)發(fā)框架,使用hybird技術(shù),只要使用前端開(kāi)發(fā)技術(shù)就可以開(kāi)發(fā)出電腦端,安卓端和ios端的站點(diǎn)程序。下面這篇文章主要給大家介紹了關(guān)于利用Ionic2 + angular4實(shí)現(xiàn)一個(gè)地區(qū)選擇組件的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-07-07
  • angular4 JavaScript內(nèi)存溢出問(wèn)題

    angular4 JavaScript內(nèi)存溢出問(wèn)題

    本篇文章主要介紹了angular4 JavaScript內(nèi)存溢出問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • 理解Angular的providers給Http添加默認(rèn)headers

    理解Angular的providers給Http添加默認(rèn)headers

    本篇文章主要介紹了理解Angular的providers給Http添加默認(rèn)headers,具有一定的參考價(jià)值,有興趣的同學(xué)可以了解一下
    2017-07-07
  • angularjs實(shí)現(xiàn)過(guò)濾并替換關(guān)鍵字小功能

    angularjs實(shí)現(xiàn)過(guò)濾并替換關(guān)鍵字小功能

    這篇文章主要為大家詳細(xì)介紹了angularjs實(shí)現(xiàn)過(guò)濾并替換關(guān)鍵字小功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • AngularJS學(xué)習(xí)筆記之依賴注入詳解

    AngularJS學(xué)習(xí)筆記之依賴注入詳解

    下面小編就為大家?guī)?lái)一篇AngularJS學(xué)習(xí)筆記之依賴注入詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05
  • Angular動(dòng)態(tài)添加、刪除輸入框并計(jì)算值實(shí)例代碼

    Angular動(dòng)態(tài)添加、刪除輸入框并計(jì)算值實(shí)例代碼

    這篇文章主要介紹了Angular動(dòng)態(tài)添加、刪除輸入框并計(jì)算值實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 詳解Angular-ui-BootStrap組件的解釋以及使用

    詳解Angular-ui-BootStrap組件的解釋以及使用

    這篇文章主要介紹了詳解Angular-ui-BootStrap組件的解釋以及使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Angular簡(jiǎn)單驗(yàn)證功能示例

    Angular簡(jiǎn)單驗(yàn)證功能示例

    這篇文章主要介紹了Angular簡(jiǎn)單驗(yàn)證功能,涉及AngularJS事件響應(yīng)、正則判定、頁(yè)面元素屬性動(dòng)態(tài)修改等相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12

最新評(píng)論