angular中的自定義指令(續(xù))

今天,接著昨天的angular自定義指令說(shuō)一下其中的其他屬性

1据忘、priority[number]屬性鹦牛,這個(gè)屬性是來(lái)規(guī)定自定義的指令的優(yōu)先級(jí)的,當(dāng)一個(gè)DOM元素上面有一個(gè)以上的指令的時(shí)候勇吊,就需要去比較指令的優(yōu)先級(jí)了曼追,優(yōu)先級(jí)高的指令先執(zhí)行榜轿。這個(gè)優(yōu)先級(jí)就是用來(lái)在執(zhí)行指令的compile函數(shù)前叶堆,先排序的,那么關(guān)于compile這個(gè)函數(shù)茸时,我們會(huì)在下面仔細(xì)的說(shuō)下针史。

2晶伦、terminal[boolean]屬性,該參數(shù)用來(lái)定義是否停止當(dāng)前元素上比本指令優(yōu)先級(jí)低的指令啄枕,如果值為true婚陪,就是正常情況,按照優(yōu)先級(jí)高低的順序來(lái)執(zhí)行频祝,如果設(shè)置為false泌参,就不會(huì)執(zhí)行當(dāng)前元素上比本指令優(yōu)先級(jí)低的指令。

3常空、link[function]屬性沽一,在上面的例子中,我們自定義的指令其實(shí)沒(méi)有多大意義漓糙,這只是一個(gè)最簡(jiǎn)單的指令铣缠,有好多的屬性我們都沒(méi)有為他定義,所以沒(méi)有多大用途昆禽。比如這個(gè)link函數(shù)蝗蛙,它包括三個(gè)參數(shù):scope、element醉鳖、attrs歼郭。這個(gè)link函數(shù)主要是用來(lái)添加對(duì)DOM元素的事件監(jiān)聽(tīng)、監(jiān)視模型屬性變化辐棒、以及更新DOM的病曾。它里面三個(gè)參數(shù):

一:scope參數(shù)牍蜂,在我們沒(méi)有為指令定義scope屬性的時(shí)候,那么他代表的就是父controller的scope泰涂。

二:element參數(shù)鲫竞,就是指令的jQLite(jQuery的子集)包裝DOM元素。如果你在引入AngularJS之前引入了jQuery逼蒙,那么這個(gè)元素就是jQuery元素从绘,而不是jQLite元素。由于這個(gè)元素已經(jīng)被jQuery/jQLite包裝了是牢,所以我們就在進(jìn)行DOM操作的時(shí)候就不需要再使用 $()來(lái)進(jìn)行包裝僵井。

三:attrs參數(shù),它包含了該指令所在元素的屬性的標(biāo)準(zhǔn)化參數(shù)對(duì)象驳棱。

4批什、scope[boolean or object]屬性,該屬性是用來(lái)定義指令的scope的范圍社搅,默認(rèn)情況下是false驻债,也就是說(shuō)該指令繼承了父controller的scope,可以隨意的使用父controller的scope里的屬性形葬,但是這樣的話就會(huì)污染到父scope里的屬性合呐,這樣是不可取的。所以我們可以讓scope取以下兩個(gè)值:true和{}笙以。

當(dāng)為true的時(shí)候淌实,表示讓Angular給指令創(chuàng)建一個(gè)繼承于父scope的scope。

eg:

let myapp=angular.module('myapp',[])

myapp.controller('myctrl',['$scope',function($scope) {

? ? ? ? ?$scope.color='red';

}])

myapp.directive('hello',function() {

? ? ? ?return{

? ? ? ? ? ? ? ?restrict:'AECM',

? ? ? ? ? ? ? ?replace:true,

? ? ? ? ? ? ? ?template:'click me',

? ? ? ? ? ? ? ?scope:true猖腕,

? ? ? ? ? ? ? ?link:function(scope,elements,attrs) {

? ? ? ? ? ? ? ? ? ? ? ? ?elements.bind('click',function() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? elements.css('background-color','blue');

? ? ? ? ? ? ? ? ? ? ? ? ?})

? ? ? ? ? ? ? ?}

? ? ? ? ?}

})

這里我們?yōu)楦竤cope定義了一個(gè)color的屬性拆祈,并賦值為red,在hello指令的scope屬性中谈息,我們給了true,所以angular就為這個(gè)指令創(chuàng)建了一個(gè)繼承于父scope的scope凛剥,然后在template屬性中侠仇,我們用{{}}使用了從父scope中繼承過(guò)來(lái)的color屬性,所以按鈕會(huì)是紅色的犁珠。


當(dāng)為{}的時(shí)候逻炊,表示創(chuàng)建一個(gè)隔離的scope,不會(huì)繼承父scope的屬性犁享。但是在有的時(shí)候我們也要需要訪問(wèn)父scope里的屬性或者方法余素,那么我們應(yīng)該怎么辦呢。angular早就為我們想到了這一點(diǎn)炊昆,有以下的三個(gè)辦法可以讓我們記性上面的操作:

一:使用@實(shí)現(xiàn)單向綁定桨吊,如果我們只給scope的這個(gè){}值的話威根,那么上面代碼的按鈕的背景色將會(huì)是灰色的。

视乐,而如果我們需要使用父scope的color屬性的時(shí)候洛搀,我們可以這樣寫(xiě):

eg:

scope{

? ? ? ? color:'@color'

}

<hello color="{{color}}"></hello>

這里有兩點(diǎn)需要注意:1、scope里的屬性color代表的是模板{{}}這個(gè)表達(dá)式里面的color佑淀,兩者必須一致留美。2、scope里的屬性color的值伸刃,也就是@后面的color谎砾,表示的是下面的HTML元素里的屬性color,所以這兩者也必須一致捧颅,當(dāng)這里的屬性名和模板里表達(dá)式{{}}里面使用的名稱(chēng)相同的話景图,就可以省略掉@后面的屬性名了,然后寫(xiě)成下面的形式隘道。

scope{

? ? ? ?color:'@'

}

從指令中scope的值可以看出症歇,指令模板中的表達(dá)式{{}}里的color的指向的是當(dāng)前元素元素的color屬性,這個(gè)color屬性的值就是父scope的屬性color的值谭梗。父scope把他的color屬性值傳遞給了當(dāng)前元素的color屬性忘晤,然后color屬性又把值傳遞給了模板中表達(dá)式里的color,這個(gè)過(guò)程是單向的激捏。

二:使用=實(shí)現(xiàn)雙向綁定

myapp.directive('hello',function() {

? ? ? ?return{

? ? ? ? ? ? ? ?restrict:'AECM',

? ? ? ? ? ? ? ?replace:true,

? ? ? ? ? ? ? ?template:'click me',

? ? ? ? ? ? ? ?scope:{

? ? ? ? ? ? ? ? ? ? ?color:'='

? ? ? ? ? ? ? ?},

? ? ? ? ? ? ? ?link:function(scope,elements,attrs) {

? ? ? ? ? ? ? ? ? ? ? ? elements.bind('click',function() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? elements.css('background-color','blue');

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? scope.$apply(function() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? scope.color='pink';

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ?}

? ? ? ? ? }

})

<hello color="{{color}}"></hello>

<input type="text" ng-model="color"/>

這里我們給指令的scope中的color屬性和父scope中的color屬性進(jìn)行了雙向綁定设塔,并且給指令的link函數(shù)里,添加了一個(gè)單擊事件远舅,點(diǎn)擊按鈕會(huì)讓按鈕的顏色發(fā)生變化闰蛔,并且改變指令scope的color屬性的值,再給HTML頁(yè)面中加了一個(gè)input標(biāo)簽图柏,輸出或者輸入父scope的color屬性的值序六。這里有一個(gè)地方需要注意:當(dāng)前元素的屬性名的值不用再加上{{}}這個(gè)表達(dá)式了,因?yàn)檫@里父scope傳遞的是一個(gè)真實(shí)的scope數(shù)據(jù)模型蚤吹,而不是簡(jiǎn)單的字符串例诀,所以這樣我們就可以傳遞簡(jiǎn)單的字符串、數(shù)組裁着、甚至復(fù)雜的對(duì)象給指令的scope》蓖浚現(xiàn)在讓我們來(lái)看看點(diǎn)擊這個(gè)按鈕將會(huì)發(fā)生什么。

這里我們能看到二驰,按鈕的顏色變成了粉色的扔罪,說(shuō)明點(diǎn)擊讓指令的scope的color屬性發(fā)生了變化,從而導(dǎo)致按鈕的顏色發(fā)生了變化桶雀。但是這里不僅僅是按鈕發(fā)生了變化矿酵,注意看唬复,input表單里的值也變成了pink,這就說(shuō)明父scope的color屬性也發(fā)生了變化坏瘩。 另外盅抚,再讓我們來(lái)給input里面輸入一個(gè)顏色,看看發(fā)生什么變化倔矾。

妄均,可以看出當(dāng)我們?cè)诒韱卫镙斎肓硗庖环N顏色的時(shí)候,按鈕的顏色也發(fā)生了變化哪自,這就說(shuō)明指令的scope的color屬性被改變了丰包。綜上我們可以發(fā)現(xiàn)使用'='實(shí)現(xiàn)的是雙向綁定。

三:使用&調(diào)用父scope里的方法

let myapp=angular.module('myapp',[])

myapp.controller('myctrl',['$scope',function($scope) {

? ? ? ?$scope.color='red';

? ? ? ?$scope.sayhello=function() {

? ? ? ? ? ? ?alert('hello');

? ? ? ?};

}])

myapp.directive('hello',function() {

? ? ? ?return{

? ? ? ? ? ? ?restrict:'AECM',

? ? ? ? ? ? ?replace:true,

? ? ? ? ? ? ?template:'click me',

? ? ? ? ? ? ?scope:{

? ? ? ? ? ? ? ? ? ? ?color:'=',

? ? ? ? ? ? ? ? ? ? ?sayhello:'&'

? ? ? ? ? ? ?},

? ? ? ? ? ? ?link:function(scope,elements,attrs) {

? ? ? ? ? ? ? ? ? ? ? elements.bind('click',function() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?elements.css('background-color','blue');

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?scope.$apply(function() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?scope.color='pink';

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?})

? ? ? ? ? ? ? ? ? ? ? ?})

? ? ? ? ? ? ? ? }

? ? ? ? }

})

這里我們也有兩個(gè)地方需要注意:1壤巷、我們不僅需要在模板中使用ng-click指令邑彪,綁定上要調(diào)用的父scope中的方法,而且要在給當(dāng)前元素添加一個(gè)屬性胧华,并且這個(gè)屬性指向要調(diào)用的父scope的方法寄症。2、指令scope的屬性sayhello矩动、當(dāng)前元素的屬性sayhello有巧、模板綁定的事件方法名sayhello這三者要一致。那么這樣我們就可以點(diǎn)擊按鈕悲没,彈出一個(gè)對(duì)話框了篮迎。

5、compile[function]參數(shù)示姿,該方法有兩個(gè)參數(shù)element甜橱,attrs,第一個(gè)參數(shù)element指指令所在的元素栈戳,第二個(gè)attrs指元素上賦予的參數(shù)的標(biāo)準(zhǔn)化列表岂傲。這里我們也有個(gè)地方需要注意:compile 函數(shù)不能訪問(wèn) scope,并且必須返回一個(gè) link 函數(shù)子檀。但是如果沒(méi)有設(shè)置 compile 函數(shù)镊掖,你可以正常地配置 link 函數(shù),(有了compile命锄,就不能用link堰乔,link函數(shù)由compile返回)偏化。

myapp.directive('hello',function() {

? ? ? return{

? ? ? ? ? restrict:'AECM',

? ? ? ? ? replace:true,

? ? ? ? ? translude:true,

? ? ? ? ? template:'click me',

? ? ? ? ? scope:{

? ? ? ? ? ? ? ?color:'=',

? ? ? ? ? ? ? ?sayhello:'&'

? ? ? ? ?},

? ? ? ? ?compile:function(element,attrs) {

? ? ? ? ? ? ?returnfunction(scope,elements,attrs) {

? ? ? ? ? ? ? ? ?elements.bind('click',function() {

? ? ? ? ? ? ? ? ? ? ?elements.css('background-color','blue');

? ? ? ? ? ? ? ? ? ? ?scope.$apply(function() {

? ? ? ? ? ? ? ? ? ? ? ? ? scope.color='pink';

? ? ? ? ? ? ? ? ? ? ?})

? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? };

? ? ? ? ? }

? ? ? }

})

現(xiàn)在讓我們來(lái)點(diǎn)擊這個(gè)按鈕

我們發(fā)現(xiàn)脐恩,這里點(diǎn)擊按鈕之后發(fā)生的事情和前面用link屬性的一樣,這其實(shí)是沒(méi)有多少差別的侦讨。

其實(shí)在大多數(shù)的情況下驶冒,我們只需要使用 link 函數(shù)苟翻。這是因?yàn)榇蟛糠值闹噶钪恍枰紤]注冊(cè)事件監(jiān)聽(tīng)、監(jiān)視模型骗污、以及更新DOM等崇猫,這些都可以在 link 函數(shù)中完成。 但是對(duì)于像 ng-repeat 之類(lèi)的指令需忿,需要克隆和重復(fù) DOM 元素多次诅炉,在 link 函數(shù)執(zhí)行之前由 compile 函數(shù)來(lái)完成。那么為什么我們需要兩個(gè)分開(kāi)的函數(shù)來(lái)完成生成過(guò)程屋厘,為什么不能只使用一個(gè)涕烧?要回答好這個(gè)問(wèn)題,我們需要理解指令在Angular中是如何被編譯的汗洒!

6议纯、指令是如何被編譯的

當(dāng)我們的angular應(yīng)用引導(dǎo)啟動(dòng)的時(shí)候,angular將會(huì)使用$compile服務(wù)遍歷DOM元素溢谤,在所有的指令都被識(shí)別之后瞻凤,將會(huì)調(diào)用指令的compile方法,返回一個(gè)link函數(shù)世杀,然后將這個(gè)link函數(shù)添加到稍后執(zhí)行的 link 函數(shù)列表中阀参,這個(gè)過(guò)程被稱(chēng)為編譯階段。像ng-repeat這樣的指令玫坛,需要被重復(fù)克隆很多次结笨,compile函數(shù)只在編譯階段被執(zhí)行一次,并且復(fù)制這些模板湿镀,但是link 函數(shù)會(huì)針對(duì)每個(gè)被復(fù)制的實(shí)例被執(zhí)行炕吸。所以分開(kāi)處理,讓我們?cè)谛阅苌嫌幸欢ǖ奶岣撸ㄟ@句話有點(diǎn)不太理解勉痴,我是從別的地方copy過(guò)來(lái)的赫模。

7、controller[string or function]和require[string or string[]]參數(shù),當(dāng)我們想要允許其他的指令和你的指令發(fā)生交互時(shí)蒸矛,我們就需要使用 controller 函數(shù)瀑罗。當(dāng)另一個(gè)指令想要交互時(shí),它需要聲明它對(duì)你的指令 controller 實(shí)例的引用(require)雏掠。

myapp.directive('hello',function() {

? ? ? return{

? ? ? ? ? ?scope:{},

? ? ? ? ? ?require:'^he',

? ? ? ? ? ?compile:function(element,attrs) {

? ? ? ? ? ? ? ? returnfunction(scope,elements,attrs,cntIns) {

? ? ? ? ? ? ? ? ? ? ? cntIns.fn()

? ? ? ? ? ? ? ? };

? ? ? ? ? ?}

? ? ? }

})

myapp.directive('he',function() {

? ? ? ?return{

? ? ? ? ? ? ?restrict:'AE',

? ? ? ? ? ? ?scope:{},

? ? ? ? ? ? ?controller:function($scope, $compile, $http) {

? ? ? ? ? ? ? ? ? this.fn=function() {

? ? ? ? ? ? ? ? ? alert('hello');

? ? ? ? ? ? ?};

? ? ? ? ?}

? ? }

})

<he>

<hello color="color"sayhello="sayhello()"></hello>

</he>

當(dāng)頁(yè)面加載完畢之后斩祭,會(huì)彈出一個(gè)對(duì)話框。

好了上面就是我這段時(shí)間學(xué)習(xí)angular乡话,所了解到的指令的知識(shí)摧玫,就先寫(xiě)到這里了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绑青,一起剝皮案震驚了整個(gè)濱河市诬像,隨后出現(xiàn)的幾起案子屋群,更是在濱河造成了極大的恐慌,老刑警劉巖坏挠,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芍躏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡降狠,警方通過(guò)查閱死者的電腦和手機(jī)对竣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)榜配,“玉大人柏肪,你說(shuō)我怎么就攤上這事〗媾疲” “怎么了烦味?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)壁拉。 經(jīng)常有香客問(wèn)我谬俄,道長(zhǎng),這世上最難降的妖魔是什么弃理? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任溃论,我火速辦了婚禮,結(jié)果婚禮上痘昌,老公的妹妹穿的比我還像新娘钥勋。我一直安慰自己,他們只是感情好辆苔,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布算灸。 她就那樣靜靜地躺著,像睡著了一般驻啤。 火紅的嫁衣襯著肌膚如雪菲驴。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天骑冗,我揣著相機(jī)與錄音赊瞬,去河邊找鬼。 笑死贼涩,一個(gè)胖子當(dāng)著我的面吹牛巧涧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遥倦,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼谤绳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起闷供,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎统诺,沒(méi)想到半個(gè)月后歪脏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粮呢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年婿失,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啄寡。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡豪硅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挺物,到底是詐尸還是另有隱情懒浮,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布识藤,位于F島的核電站砚著,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏痴昧。R本人自食惡果不足惜稽穆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赶撰。 院中可真熱鬧舌镶,春花似錦、人聲如沸豪娜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瘤载。三九已至骂澄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惕虑,已是汗流浹背坟冲。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留溃蔫,地道東北人健提。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像伟叛,于是被迫代替她去往敵國(guó)和親私痹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容