原創(chuàng)性聲明:本文完全為筆者原創(chuàng)灰署,請尊重筆者勞動力判帮。轉(zhuǎn)載務(wù)必注明原文地址局嘁。
指令詳解
一個指令的定義應(yīng)當是如下這個樣子:
code:
angular.module('myApp', [])
.directive('myDirective', function (UserDefinedService) {
// 指令定義放在這里
});
其中,fun中的注入?yún)?shù)為angular自帶或用戶定義的服務(wù)晦墙,需要在指令內(nèi)部中調(diào)用悦昵。分析其結(jié)構(gòu):
-
angular.module('myApp', [])
:是聲明整個應(yīng)用對象的。 -
.directive('myDirective', fun(){})
:directive方法接受兩個參數(shù):字符串和函數(shù)晌畅。
字符串myDirective
是用以在視圖中引用特定的指令但指。而函數(shù)則返回一個對象,這個對象中定義了指令的全部行為踩麦,$compile服務(wù)利用這個方法返回的對象枚赡,在DOM調(diào)用指令時來構(gòu)造指令的行為氓癌。即:
angular.module('myApp', [])
.directive('myDirective', function (UserDefinedService) {
return {
}
});
當然除了返回一個對象谓谦,其實也可以返回一個函數(shù):
angular.module('myApp', [])
.directive('myDirective', function (UserDefinedService) {
return function() { //此時這個函數(shù)叫做“鏈接傳遞函數(shù)”
}
});
但是一般地,都采用返回對象的形式贪婉,這樣指令的定義可以更豐富反粥。返回函數(shù)的情況只有在定義非常簡單的指令時才可能會使用。
下面看指令中第二個參數(shù)——函數(shù)——返回對象的詳細配置FS亍2哦佟!
<i style="color:red">code:</i>
angular.module('myApp', [])
.directive('myDirective', function() {
return {
restrict: String,
priority: Number,
terminal: Boolean,
template: String or Template Function:
function(tElement, tAttrs){...},
templateUrl: String,
replace: Boolean or String,
scope: Boolean or Object,
transclude: Boolean,
controller: String or
function(scope, element, attrs, transclude, otherInjectables){...},
controllerAs: String,
require: String,
link: function(scope, iElement, iAttrs){...},
compile: //該屬性值返回的是一個對象或函數(shù)尤蒿,如下所示:
function(tElement, tAttrs, transclude) {
return {
pre: function(scope, iElement, iAttrs, controller){...},
post: function(scope, iElement, iAttrs, controller){...}
}
//或者
return function postLink(...){...}
}
}
});
下面分別對各個配置項進行詳細說明:
1. restrict
- 非必須
- 可選值:'EACM'
EACM指的是指令在DOM視圖中的應(yīng)用形式郑气,如下:
E: (元素)
<my-directive></my-directive>
A: (屬性,默認值)
<div my-directive="expression"></div>
C: (類名)
<div class="my-directive:expression;"></div>
M: (注釋)
<--directive:my-directive expression-->
這些值可以單獨使用腰池,也可以混合使用尾组。其中A是推薦的方式,因為它的兼容性更好示弓,也更容易擴充讳侨。
2. priority
優(yōu)先級。它的作用是聲明指令的優(yōu)先級奏属,當多個指令用在同一個DOM元素上時跨跨,哪個會先執(zhí)行呢?就取決于這個參數(shù)囱皿。如果兩個指令的優(yōu)先級一樣勇婴,那么聲明在前的會先被調(diào)用并執(zhí)行。
例如 ng-repeat
的優(yōu)先級就是1000嘱腥,因此咆耿,它總是比其他指令更優(yōu)先執(zhí)行。
3. terminal
Boolean值爹橱,它的作用是告訴angularJS是否停止運行當前元素上比本指令優(yōu)先級更低的指令萨螺,但與當前指令優(yōu)先級同級的指令仍然會被執(zhí)行的窄做。如下面的例子:
<div>
<p my-terminal-test1 my-terminal-test2></p>
</div>
angular.module('angularLearningApp')
.directive('myTerminalTest1', function() {
return {
restrict: 'A',
priority: 1,
template: '百度',
link: function (scope, element, attrs) {
console.log("myTerminalTest1");
}
}
})
.directive('myTerminalTest2', function() {
return {
restrict: 'A',
priority: 2,
terminal: false, //現(xiàn)將terminal設(shè)置為false
link: function(scope, element, attrs) {
console.log("myTerminalTest2");
element[0].textContent += '谷歌';
}
}
});
顯然div中的內(nèi)容是 百度谷歌
,如果將terminal設(shè)置為true慰技,則顯示的結(jié)果為 谷歌
,這是因為 myTerminalTest1
指令的優(yōu)先級低于 myTerminalTest2
椭盏,而terminal為true因此,低于它的指令將不被執(zhí)行吻商。
4. template
template有兩種形式:
- String //模板字符串
- function(tElement, tAttrs){ ...; return templateStr;//返回模板字符串}
需要注意的是: template返回的模板中掏颊,DOM結(jié)構(gòu)中必須存在一個根節(jié)點。在實際的開發(fā)中艾帐,更常使用的是templateUrl乌叶,因為可以避免字符串拼接,那是可讀性柒爸、維護性很差的方式准浴。另外,template中最為重要的東西是controller與本指令中template變量的數(shù)據(jù)傳遞捎稚。
5. templateUrl
同樣有兩種形式:
- String // 模板html文件路徑
- function(tElement, tAttrs){...; return templatePath;//返回模板html路徑}
默認情況下乐横,調(diào)用指令會在后臺通過ajax請求html模板文件,有兩個特別需要注意的:
- 在本地開發(fā)時今野,需要在后臺運行一個本地服務(wù)器葡公,用以從文件系統(tǒng)加載HTML模板,否則會導致Cross Origin Request Script(CORS)錯誤条霜。
- 模板加載是異步的催什,意味著編譯和鏈接要暫停,等待模板加載完成宰睡。
通過Ajax異步加載大量的模板將嚴重拖慢一個客戶端應(yīng)用的速度蒲凶。為了避免延遲,可以在部
署應(yīng)用之前對HTML模板進行緩存夹厌。在大多數(shù)場景下緩存都是一個非常好的選擇豹爹,因為AngularJS
通過減少請求數(shù)量提升了性能。更多關(guān)于緩存的內(nèi)容請查看第28章矛纹。
模板加載后臂聋, AngularJS會將它默認緩存到$templateCache服務(wù)中。在實際生產(chǎn)中或南,可以提
前將模板緩存到一個定義模板的JavaScript文件中孩等,這樣就不需要通過XHR來加載模板了。更多內(nèi)容請查看第34章采够。
6. replace
默認值是false,表示模板的內(nèi)容將會被插入到視圖中應(yīng)用指令元素的內(nèi)部肄方。如果設(shè)置為true,則表示替代蹬癌,即插入到視圖中時权她,應(yīng)用指令的html元素將被刪除虹茶,取而代之的是html模板。
7. scope
可選參數(shù)
- boolean 默認是false隅要,即該指令并不會創(chuàng)建新的作用域蝴罪,改指令內(nèi)部或外部的作用域是一樣的。當為true時步清,會從父作用域繼承并創(chuàng)建一個新的作用域?qū)ο笠牛丛撝噶顑?nèi)部和外部并不是在一個作用域內(nèi)。
- Object :設(shè)置此屬性也被稱為“隔離作用域”廓啊。
scope為Boolean時
code:
<div ng-init="someProperty = 'some data'"></div>
<div ng-init="siblingProperty='moredata'">
Inside Div Two: { { aThirdProperty } }
<div ng-init="aThirdProperty = 'data for 3rd property'"
ng-controller="SomeController">
Inside Div Three: { { aThirdProperty } }
<div ng-controller="SecondController">
Inside Div Four: { { aThirdProperty } }
<br>
Outside myDirective: { { myProperty } }
<div my-directive ng-init="myProperty = 'wow, this is cool'">
Inside myDirective: { { myProperty } }
<div>
</div>
</div>
</div>
angular.module('myApp', [])
.controller('SomeController', function($scope) {
// 可以留空欢搜,但需要被定義
})
.controller('SecondController', function($scope) {
// 同樣可以留空
});
angular.module('myApp', [])
.directive('myDirective', function() {
return {
restrict: 'A',
//scope: true
};
});
首先,將把 scope:true
注釋掉即設(shè)置scope為默認的false谴轮。此時的結(jié)果是:
view:
<div ng-init="someProperty = 'some data'"></div>
<div ng-init="siblingProperty='moredata'">
Inside Div Two: {{ aThirdProperty }}
<div ng-init="aThirdProperty = 'data for 3rd property'"
ng-controller="SomeController">
Inside Div Three:{{ aThirdProperty }}
<div ng-controller="SecondController">
Inside Div Four:{{ aThirdProperty }}<br>
Outside myDirective: {{ myProperty }}
<div my-directive-scope-test ng-init="myProperty = 'wow, this is cool'">
Inside myDirective: {{ myProperty }}<div>
</div>
</div>
</div>
顯而易見炒瘟,Outside myDirective和Inside myDirecitve都將是有值的,即使myProperty的值是在指令標簽中定義的书聚,但因為指令中的配置項scope為false唧领,該指令并沒有產(chǎn)生一個新的作用域藻雌,因此雌续,在這個指令標簽內(nèi)部和外部都是在一個作用域下,即:SecondController對應(yīng)的作用域下胯杭,所以值都是有的驯杜。
但如果將 scope:true
釋放掉,那么該指令就會產(chǎn)生一個獨立作用域做个,此作用域繼承父作用域鸽心,但是在該作用域中定義的變量myProperty,就無法在該指令外部調(diào)用了居暖,因此顽频,結(jié)果就是:
Outside myDirective:
Inside myDirective: wow, this is cool
這就是scope為boolean值時的作用。
scope為Object時————隔離作用域
設(shè)置scope配置屬性值為Object時太闺,指令的模板就無法訪問外部作用域了糯景。也因此,不受外部作用域變量的影響省骂,因此蟀淮,隔離作用域常用來創(chuàng)建可復用的指令組件。
code:
<div ng-controller='SomeController2'>
Outside myDirective: { { myProperty2 } }
<div my-directive-scope-test2 ng-init="myProperty2 = 'wow, this is cool!'">
Inside myDirective: { { myProperty2 } }
</div>
</div>
angular.module('myApp', [])
.controller('SomeController2', function($scope) {
})
.directive('myDirectiveScopeTest2', function() {
return {
restrict: 'A',
scope: {}, //對象
priority: 100,
template: '<div>Inside myDirective: { { myProperty2 } }</div>'
};
});
view:
<div ng-controller='SomeController2'>
Outside myDirective: {{ myProperty2 }}
<div my-directive-scope-obj-test ng-init="myProperty2 = 'wow, this is cool钞澳!'">
Inside myDirective: {{ myProperty2 }}
</div>
</div>
Inside myDirective
中將不會出現(xiàn)值怠惶,沒錯,因為scope隔離了模板與外界作用域轧粟。
但是Outside myDirective
中將存在值策治,為什么呢脓魏?<b>難道隔離作用域只是隔離了模板與外界作用域,而當前指令應(yīng)用的DOM元素中用其他指令定義的變量仍然可以在外面被訪問通惫?</b>
為此轧拄,在此進行對比演示:
code:
<div ng-controller="ScopeValueCompareController"
ng-init="myProperty='wow,this is so cool'">
Surrounding scope: {{ myProperty }}
<div my-inherit-scope-directive></div>
<div my-directive></div>
</div>
angular.module('myApp', [])
.controller('ScopeValueCompareController', function($scope) {
})
.directive('myDirective3', function() {
return {
restrict: 'A',
template: 'Inside myDirective, isolate scope: {{ myProperty }}',
scope: {}
};
})
.directive('myInheritScopeDirective', function() {
return {
restrict: 'A',
template: 'Inside myDirective, isolate scope: {{ myProperty }}',
scope: true
};
});
view:
<div ng-controller="ScopeValueCompareController"
ng-init="myProperty3='wow,this is so cool'">
Surrounding scope: {{ myProperty3 }}
<div my-directive3></div>
<div my-inherit-scope-directive></div>
</div>
scope為{}時,指令內(nèi)模板作用域被隔離開讽膏,所以是沒有值得檩电。scope為true時,指令內(nèi)新建了一個作用域府树,但他繼承父級作用域(這里是ScopeValueCompareController對應(yīng)的作用域)俐末,因此可以訪問外部變量。
<b style="color:red">scope為對象時的綁定策略</b>
scope為Object時奄侠,像上面的空對象的情況肯定是不適用的卓箫。angularJS提供了幾種方法,可以將指令內(nèi)部的隔離作用域和指令外部的作用域進行數(shù)據(jù)綁定垄潮。
-
@
(or@attr
) : 本地作用域?qū)傩耘胱洹J褂?@
符號將本地作用域與DOM屬性的值進行綁定,指令內(nèi)部作用域可以訪問并使用外部作用域的變量弯洗,<b>常用于DOM中屬性值為固定參數(shù)</b>旅急。 -
=
(or=attr
) : 雙向綁定。使用=
符號將本地作用域中的屬性和DOM屬性的值進行雙向綁定牡整,那么當DOM屬性值隨時改變時藐吮,指令中的值也會改變,同時反過來也是一樣的逃贝。<b>常用于DOM中對應(yīng)屬性值是動態(tài)的谣辞,如ng-model</b>。 -
&
(or&attr
) : 父級作用域綁定沐扳。<b>主要用于運行其中的函數(shù)泥从,也就是說這個值在指令中設(shè)置后,會生成一個指向父級作用域的包裝函數(shù)沪摄。如果要調(diào)用帶有參數(shù)的父方法躯嫉,則需要在DOM指令屬性值的函數(shù)形參中傳入一個對象,對象的鍵是參數(shù)名卓起,值是參數(shù)值和敬。</b>
如下面的例子:
code:
<input type="text" ng-model="to"/>
<!-- 調(diào)用指令 -->
<div scope-example ng-model="to" on-send="sendMail(email)"
from-name="ari@fullstack.io">
</div>
自定義指令 scope-example
中如果要訪問此處的數(shù)據(jù)(模型to
、 函數(shù)方法sendMail(email)
以及字符串"ari@fullstack.io"
)的話戏阅,就必須配置scope為對象昼弟,如下:
scope: {
ngModel: '=', // 將ngModel同指定對象綁定
onSend: '&', // 將引用傳遞給這個方法
fromName: '@' // 儲存與fromName相關(guān)聯(lián)的字符串
}
注意指令中本地變量的命名規(guī)則(駝峰法)。如果不想用駝峰法奕筐,想自定義隨便取名舱痘,也可以指定要綁定的外部DOM變量变骡,如下:
scope: {
a: '=ngModel', // 將ngModel同指定對象綁定
b: '&onSend', // 將引用傳遞給這個方法
c: '@fromName' // 儲存與fromName相關(guān)聯(lián)的字符串
}
那么a
的值就是 to
的值, b
的值就是 sendMail(email)
方法的引用芭逝,c
的值就是ari@fullstack.io
塌碌。
這就是三種綁定策略的不同以及各自的適用場景!
8. transclude
可選參數(shù)旬盯。Boolean值台妆,默認值為false。定義為true時胖翰,它會將整個DOM嵌入到指令內(nèi)部定義的模板中接剩,包括DOM中的其他指令。
<b>只有當你希望創(chuàng)建一個可以包含任意內(nèi)容的指令時萨咳, 才使用transclude: true懊缺。</b>
為了將作用域傳遞進去, scope參數(shù)的值必須通過{}或true設(shè)置成隔離作用域培他。如果沒有設(shè)
置scope參數(shù)鹃两,那么指令內(nèi)部的作用域?qū)⒈辉O(shè)置為傳入模板的作用域。嵌入允許指令的使用者方便地提供自己的HTML模板舀凛,其中可以包含獨特的狀態(tài)和行為俊扳,并對指令的各方面進行自定義√诮担看一個簡單的例子,一個包括標題和少量html內(nèi)容的側(cè)邊欄拣度。
code:
<div sidebox title="Links">
<ul>
<li>First link</li>
<li>Second link</li>
</ul>
</div>
為這個側(cè)邊欄創(chuàng)建一個簡單的指令碎绎,設(shè)置transclude為true:
angular.module('myApp', [])
.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>'
};
});
view:
<div sidebox title="Links">
<ul>
<li>First link</li>
<li>Second link</li>
</ul>
</div>
此時螃壤,在瀏覽器中生成的DOM結(jié)構(gòu)為:
<div sidebox title="Links"> <!-- a:原來DOM中應(yīng)用sidebox指令的標簽 -->
<div class="sidebox"> <!-- c:sidebox指令中定義的模板 -->
<div class="content"> <!-- c -->
<h2 class="header">{ { title } }</h2> <!-- c -->
<span class="content" ng-transclude> <!-- c -->
<ul> <!-- b 的子標簽內(nèi)容 -->
<li>First link</li> <!-- b -->
<li>Second link</li> <!-- b -->
</ul>
</span> <!-- c -->
</div> <!-- c -->
</div> <!-- c -->
</div> <!-- a -->
顯然,transclude設(shè)為true后筋帖,angularJS將該指令應(yīng)用的DOM元素(a)的內(nèi)部所有元素(b)都嵌入到了指令模板中聲明ng-transclude的元素(c)內(nèi)奸晴,并全部套入到a中,再被渲染出來日麸。
transclude和ng-transclude是聯(lián)合使用的寄啼。
9.controller
controller可以是字符串或函數(shù):
- String : 以該字符串為值去整個項目中查找同名注冊的controller
- function: 匿名構(gòu)造函數(shù)定義的內(nèi)聯(lián)controller
code:
angular.module('myApp',[])
.directive('myDirective', function() {
restrict: 'A',
controller:
function($scope, $element, $attrs, $transclude) {
// 控制器邏輯放在這里
}
});
我們可以將任意可以被注入的AngularJS服務(wù)傳遞給控制器。例如代箭,如果我們想要將$log服
務(wù)傳入控制器墩划,只需簡單地將它注入到控制器中,便可以在指令中使用它了嗡综。上面的例子乙帮,有:
- $scope :與指令元素相關(guān)聯(lián)的當前作用域
- $element: 指令元素,即當前指令應(yīng)用的DOM元素
- $attrs: 由指令元素的屬性和屬性值所組成的對象极景。如:
<div id="aDiv"class="box"></div>
的$attrs值為:{id: "aDiv", class: "box"}
- $transclude: transclude鏈接函數(shù)是實際被執(zhí)行用來克隆元素和操作DOM的函數(shù)察净。
指令的控制器和link函數(shù)可以進行互換驾茴。控制器主要是用來提供可在指令間復用的行為氢卡,但
鏈接函數(shù)只能在當前內(nèi)部指令中定義行為锈至,且無法在指令間復用。<b>由于指令可以require其他指令所使用的控制器译秦,因此控制器常被用來放置在多個指令間共享的動作峡捡。</b>
10.controllerAs
字符串。這個參數(shù)用以設(shè)置控制器的別名筑悴,以此名發(fā)布控制器棋返,并且作用域可以訪問controllerAs。
code:
angular.module('myApp')
.directive('myDirective', function() {
return {
restrict: 'A',
template: '<h4>{{ myController.msg }}</h4>',
controllerAs: 'myController',
controller: function() {
this.msg = "Hello World"
}
}
});
11. require
字符串或數(shù)組雷猪【ⅲ可選值。當值為字符串時求摇,它應(yīng)當是另一個指令的名字射沟。require是將其值所指定的指令中的控制器注入到當前指令中,并作為當前指令的link函數(shù)的第四個參數(shù)与境。而這個被注入進來的控制器(位于指令鏈接的父指令中)會首先被當前指令查找验夯,查找當然是根據(jù)require的值決定的,不過給這個值予以不同的前綴摔刁,會影響它的查找行為:
- ? 尋找require值對應(yīng)的指令中的控制器挥转,如果在指令鏈的父指令(即require的值所對應(yīng)的指令)中沒有找到需要的控制器,則當前指令中的link函數(shù)的第四個參數(shù)將會是null共屈。
- ^ 如果在指令鏈的父指令中沒有找到需要的控制器绑谣,則會進一步往指令鏈上游尋找需要的控制器。
- ?^ <b>教程的解釋是:</b>我們可選擇地加載需要的指令并在父指令鏈中進行查找拗引。
- 沒有前綴的情況: 如果沒有前綴借宵,則指令就會在自身所提供的控制器中進行查找,如果沒有找到控制器(或者沒有找到require的值所對應(yīng)的指令)矾削,就會拋出一個錯誤壤玫。
code:
<hello>
<div>hello</div>
<beautiful good>
beautiful
</beautiful>
</hello>
angular.module("myApp", [])
.directive("hello",function(){
return {
restrict : "E",
controller : function($scope){
$scope.name = "張三";
this.information = {
name : $scope.name,
age : 25,
job : "程序員"
}
},
link : function(scope){
}
}
})
.directive("beautiful",function(){
return {
restrict : "E",
require : "?good",
controller : function(){
this.name = "beautiful";
},
link : function (scope,element,attrs,good) {
console.log(good.name)
}
}
}).
directive("good",function(){
return {
restrict : "A",
require : "?^hello",
controller : function(){
this.name = "good";
},
link : function (scope,element,attrs,hello) {
console.log(hello.information)
}
}
});
12.compile
該屬性的屬性值是一個函數(shù)內(nèi)部返回一個對象,或者函數(shù)哼凯。理解compile和link函數(shù)是angularJS需要討論的高級話題之一欲间,對于了解angularJS是如何工作的是至關(guān)重要的。
本質(zhì)上断部,當我們設(shè)置了link選項猎贴,實際上是創(chuàng)建了一個postLink()鏈接函數(shù),以便compile()函數(shù)可以定義函數(shù)。
通常情況下嘱能,如果我們設(shè)置了complie()函數(shù)吝梅,說明我們希望在指令和實時數(shù)據(jù)被放到DOM中之前對DOM進行操作,在這個函數(shù)中進行諸如惹骂,添加和刪除節(jié)點等DOM操作是安全的苏携。
特別注意:compile函數(shù)和link函數(shù)是互斥的。即对粪,如果同時設(shè)置了這兩個配置項右冻,那么angularJS會選擇compile函數(shù)的返回函數(shù)作為link函數(shù),而本身link函數(shù)的配置會被完全忽略著拭。
- 編譯函數(shù)compile內(nèi)部通常用來轉(zhuǎn)換可以被安全操作的DOM節(jié)點纱扭,不要對DOM進行事件監(jiān)聽注冊。
- 鏈接函數(shù)link負責將DOM和作用域進行鏈接儡遮。
如下一個例子:
compile: function(tEle, tAttrs, transcludeFn) {
var tplEl = angular.element('<div>' +
'<h2></h2>' +
'</div>');
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) {
// 連接函數(shù)
};
}
13 link函數(shù)
link函數(shù)用來創(chuàng)建可以操作DOM的屬性乳蛾。當定義了編譯函數(shù)來取代鏈接函數(shù)時,鏈接函數(shù)是我們能提供給返回對象的第二個方法鄙币,也就是postLink函數(shù)肃叶。本質(zhì)上講,這個事實正說明了鏈接函數(shù)的作用十嘿。它會在模板編譯并同作用域進行鏈接后被調(diào)用因惭,因此它負責設(shè)置事件監(jiān)聽器,監(jiān)視數(shù)據(jù)變化和實時的操作DOM绩衷。
鏈接函數(shù)一共有四個參數(shù):
- scope : 指令用來在其內(nèi)部注冊監(jiān)聽器的作用域
- iElement: 代表實例元素蹦魔,即使用此指令的元素。在postLink函數(shù)中咳燕,我們應(yīng)該只操作這個元素和其子元素勿决,因為這些元素已經(jīng)被鏈接過了。
- iAttrs: 代表實例屬性迟郎,一個由定義在元素上的屬性組成的標準化列表剥险,可以在所有指令的鏈接函數(shù)間共享。會以javascript對象的形式進行傳遞宪肖。
- controller: 這個參數(shù)只有在當前指令存在
require
選項時才會有,否則就是undefined健爬。如果require的值是另一個指令A,那么controller的值就是這個指令A中的controller;如果require的值是另一個單獨的controller鹃答,那么當前controller的值就是這個controller礁蔗;如果require指向多個控制器,那么當前controller就是一個由這些多個控制器組成的數(shù)組设拟。
link函數(shù)是指令中最為常用的一個配置項慨仿。它和controller函數(shù)最大的區(qū)別就是功能性區(qū)分久脯,前者是用以操作DOM,后者用以指令間傳遞镰吆。
自定義指令的配置項中complie帘撰、link、controller等還有很深的水万皿,需要進一步去探究摧找。關(guān)于指令的link中如何訪問到視圖中的ng-model的值,其中也存在很多問題牢硅。