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

淺析AngularJS中的指令

 更新時(shí)間:2016年03月20日 20:29:02   作者:蜀北喬少恭  
指令(Directives)是所有AngularJS應(yīng)用最重要的部分。盡管AngularJS已經(jīng)提供了非常豐富的指令,但還是經(jīng)常需要?jiǎng)?chuàng)建應(yīng)用特定的指令

指令(Directives)是所有AngularJS應(yīng)用最重要的部分。盡管AngularJS已經(jīng)提供了非常豐富的指令,但還是經(jīng)常需要?jiǎng)?chuàng)建應(yīng)用特定的指令。

說(shuō)到AngularJS,我們首先想到的大概也就是雙向數(shù)據(jù)綁定和指令系統(tǒng)了,這兩者也是AngularJS中最為吸引人的地方。雙向數(shù)據(jù)綁定呢,感覺(jué)沒(méi)什么好說(shuō)的,那么今天我們就來(lái)簡(jiǎn)單的討論下AngularJS這個(gè)框架的指令系統(tǒng),本人也是初學(xué),查閱了一些資料,要是有一些說(shuō)的不好的地方,萬(wàn)望指出。

指令作為AngularJS中最為重要的部分,所以這個(gè)框架本身也是自帶了比較多的的指令,但是在開(kāi)發(fā)中,這些指令通常不能滿足我們的需要,所以我們也是需要自定義一些指令的。那么一個(gè)AngularJS指令在HTML代碼中可以有四種表現(xiàn)形式:

1、作為一個(gè)新的HTML元素來(lái)使用。

<hello></hello>或者<hello/>

2、作為一個(gè)元素的屬性來(lái)使用

<div hello></div>

3、作為一個(gè)元素的類來(lái)使用

<div class="hello"></div>

4、作為注釋來(lái)使用

<!--directive: hello -->

注意這里有一個(gè)陷阱,就是在“directive: hello”這個(gè)的后面要有一個(gè)空格,不然的話是沒(méi)有效果的,同時(shí)推薦注釋的方法的還是少用,如果非要追求高大上,那就隨性吧。既然指令有以上四種表現(xiàn)形式,那么具體他是怎么來(lái)定義的呢?

.directive('hello',function(){
return {
restrict:'AECM',
template:'<button>click me</button>'
}
})

上面就是定義一個(gè)指令最簡(jiǎn)單的代碼了,沒(méi)有之一。在上面的代碼中,directive()這個(gè)方法定義了一個(gè)新的指令,該方法有兩個(gè)參數(shù),第一個(gè)'hello'就是規(guī)定指令的名字為hello,第二個(gè)參數(shù)是返回指令對(duì)象的函數(shù)。那么在上面的代碼中,該函數(shù)主要使用了兩個(gè)屬性來(lái)定義這個(gè)hello指令:

1、restrict[string]這個(gè)屬性,主要是用來(lái)規(guī)定指令在HTML代碼中可以使用什么表現(xiàn)形式。A代表屬性、E代表元素、C代表類、M代表注釋。實(shí)際情況中我們一般使用AE這兩種方式。

2、template[string or function]這個(gè)屬性,規(guī)定了指令被Angular編譯和鏈接(link)后生成的HTML標(biāo)記,這個(gè)屬性可以簡(jiǎn)單到只有一個(gè)HTML文本在里面,也可以特別復(fù)雜,當(dāng)該屬性的值為function的時(shí)候,那么該方法返回的就是代表模板的字符串,同時(shí)也可以在里面使用{{}}這個(gè)表達(dá)式。

template: function () {
return '<button>click me</button>';
}

但是在一般情況下,template這個(gè)屬性都會(huì)被templateUrl取代掉,用它來(lái)指向一個(gè)外部的文件地址,所以我們通常把模板放在外部的一個(gè)HTML文件中,然后使用templateUrl來(lái)指向他。

在定義指令的時(shí)候,除了以上兩個(gè)最基礎(chǔ)的屬性外,我們還會(huì)使用到其他的很多屬性,那么下面我們就來(lái)一一的說(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、replace[boolean]屬性,這個(gè)屬性用來(lái)規(guī)定生成的HTML內(nèi)容是否會(huì)替換掉定義此指令的HTML元素。當(dāng)我們把該屬性的值設(shè)為true的時(shí)候,打開(kāi)控制臺(tái)看看你會(huì)發(fā)現(xiàn)這個(gè)指令生成的元素會(huì)是這樣的:

當(dāng)我們?cè)O(shè)置為false的時(shí)候會(huì)是這樣的:


4、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ì)象。

5、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。

var myapp=angular.module('myapp',[])
.controller('myctrl',['$scope', function ($scope) {
$scope.color='red';
}])
.directive('hello', function () {
return{
restrict:'AECM',
replace:true,
template:'<button ng-click="sayhello()" style="background-color: {{color}}">click me</button>',
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ě):

scope{
color:'@color'
}
<hello color="{{color}}"></hello>

這里有兩點(diǎn)需要注意:1、scope里的屬性color代表的是模板{{}}這個(gè)表達(dá)式里面的color,兩者必須一致。2、scope里的屬性color的值,也就是@后面的color,表示的是下面的HTML元素里的屬性color,所以這兩者也必須一致,當(dāng)這里的屬性名和模板里表達(dá)式{{}}里面使用的名稱相同的話,就可以省略掉@后面的屬性名了,然后寫(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)雙向綁定

.directive('hello', function () {
return{
restrict:'AECM',
replace:true,
template:'<button style="background-color: {{color}}">click me</button>',
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?,F(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里的方法

var myapp=angular.module('myapp',[])
.controller('myctrl',['$scope', function ($scope) {
$scope.color='red';
$scope.sayhello= function () {
alert('hello');
};
}])
.directive('hello', function () {
return{
restrict:'AECM',
replace:true,
template:'<button ng-click="sayhello()" style="background-color: {{color}}">click me</button>',
scope:{
color:'=',
sayhello:'&'
},
link: function (scope,elements,attrs) {
elements.bind('click', function () {
elements.css('background-color','blue');
scope.$apply(function () {
scope.color='pink';
})
})
}
}
})
<hello color="color" sayhello="sayhello()"></hello>
<input type="text" ng-model="color"/>

這里我們也有兩個(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ì)話框了。

6、transclude[boolean]屬性,這個(gè)屬性用來(lái)讓我們規(guī)定指令是否可以包含任意內(nèi)容

.directive('hello', function () {
return{
restrict:'AECM',
replace:true,
transclude:true,
scope:{},
template:'<div ng-transclude></div>',
}
})
<hello>
hello
<span>{{color}}</span>
</hello>

當(dāng)他的值為true的時(shí)候,這是頁(yè)面上輸出的值。當(dāng)為false的時(shí)候,頁(yè)面上將會(huì)是空白的。這里有一個(gè)地方需要注意,就是<span>{{color}}</span>,這里的color是父scope里的color。并不是指令里的scope的color屬性。

7、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返回)。

.directive('hello', function () {
return{
restrict:'AECM',
replace:true,
translude:true,
template:'<button ng-click="sayhello()" style="background-color: {{color}}">click me</button>',
scope:{
color:'=',
sayhello:'&'
},
compile: function (element,attrs) {
return function (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 之類的指令,需要克隆和重復(fù) DOM 元素多次,在 link 函數(shù)執(zhí)行之前由 compile 函數(shù)來(lái)完成。那么為什么我們需要兩個(gè)分開(kāi)的函數(shù)來(lái)完成生成過(guò)程,為什么不能只使用一個(gè)?要回答好這個(gè)問(wèn)題,我們需要理解指令在Angular中是如何被編譯的!

8、指令是如何被編譯的

當(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ò)程被稱為編譯階段。像ng-repeat這樣的指令,需要被重復(fù)克隆很多次,compile函數(shù)只在編譯階段被執(zhí)行一次,并且復(fù)制這些模板,但是link 函數(shù)會(huì)針對(duì)每個(gè)被復(fù)制的實(shí)例被執(zhí)行。所以分開(kāi)處理,讓我們?cè)谛阅苌嫌幸欢ǖ奶岣撸ㄟ@句話有點(diǎn)不太理解,我是從別的地方copy過(guò)來(lái)的。原文在這里http://blog.jobbole.com/62249/)。

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

.directive('hello', function () {
return{
scope:{},
require:'^he',
compile: function (element,attrs) {
return function (scope,elements,attrs,cntIns) {
cntIns.fn()
};
}
}
})
.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ě)到這里了。

相關(guān)文章

  • Angular使用過(guò)濾器uppercase/lowercase實(shí)現(xiàn)字母大小寫(xiě)轉(zhuǎn)換功能示例

    Angular使用過(guò)濾器uppercase/lowercase實(shí)現(xiàn)字母大小寫(xiě)轉(zhuǎn)換功能示例

    這篇文章主要介紹了Angular使用過(guò)濾器uppercase/lowercase實(shí)現(xiàn)字母大小寫(xiě)轉(zhuǎn)換功能,涉及AngularJS過(guò)濾器針對(duì)字符串轉(zhuǎn)換的簡(jiǎn)單使用技巧,需要的朋友可以參考下
    2018-03-03
  • Angular管道PIPE的介紹與使用方法

    Angular管道PIPE的介紹與使用方法

    這篇文章主要給大家介紹了關(guān)于Angular管道PIPE的相關(guān)資料,管道的作用就是傳輸,并且不同的管道具有不同的作用,需要的朋友可以參考下
    2021-06-06
  • 使用AngularJS對(duì)路由進(jìn)行安全性處理的方法

    使用AngularJS對(duì)路由進(jìn)行安全性處理的方法

    這篇文章主要介紹了使用AngularJS對(duì)路由進(jìn)行安全性處理的方法,AngularJS是一款高人氣的JavaScript庫(kù),需要的朋友可以參考下
    2015-06-06
  • Angular1.x自定義指令實(shí)例詳解

    Angular1.x自定義指令實(shí)例詳解

    這篇文章主要介紹了Angular1.x自定義指令,結(jié)合實(shí)例形式分析了Angular1.x自定義指令的實(shí)現(xiàn)與使用方法,以及相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2017-03-03
  • AngularJS入門教程之AngularJS 模板

    AngularJS入門教程之AngularJS 模板

    本文主要介紹AngularJS 模板,這里整理了詳細(xì)相關(guān)資料,并附示例代碼,有興趣的小伙伴可以參考下
    2016-08-08
  • AngulerJS學(xué)習(xí)之按需動(dòng)態(tài)加載文件

    AngulerJS學(xué)習(xí)之按需動(dòng)態(tài)加載文件

    本篇文章主要介紹了AngulerJS學(xué)習(xí)之按需動(dòng)態(tài)加載文件,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • AngularJS基礎(chǔ) ng-click 指令示例代碼

    AngularJS基礎(chǔ) ng-click 指令示例代碼

    本文介紹AngularJS ng-click 指令,這里整理了ng-click指令的基礎(chǔ)知識(shí)并且附有簡(jiǎn)單示例代碼和實(shí)現(xiàn)效果圖,有需要的小伙伴參考下
    2016-08-08
  • ng2學(xué)習(xí)筆記之bootstrap中的component使用教程

    ng2學(xué)習(xí)筆記之bootstrap中的component使用教程

    現(xiàn)在angular2已經(jīng)除了集成的angular-cli,建議大家可以基于這個(gè)來(lái)快速開(kāi)發(fā)ng2的項(xiàng)目,不用自己再搭建環(huán)境。接下來(lái)通過(guò)本文給大家介紹 bootstrap中的component使用教程,需要的朋友可以參考下
    2017-03-03
  • 關(guān)于angular瀏覽器兼容性問(wèn)題的解決方案

    關(guān)于angular瀏覽器兼容性問(wèn)題的解決方案

    這篇文章主要給大家介紹了關(guān)于angular瀏覽器兼容性問(wèn)題的解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用angular具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 前后端如何實(shí)現(xiàn)登錄token攔截校驗(yàn)詳解

    前后端如何實(shí)現(xiàn)登錄token攔截校驗(yàn)詳解

    這篇文章主要給大家介紹了關(guān)于前后端如何實(shí)現(xiàn)登錄token攔截校驗(yàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09

最新評(píng)論