您好,登錄后才能下訂單哦!
Angular指令
定義一個(gè)指令的方法非常簡單,只需要調(diào)用`directive`方法即可:
var app=angular.module('myapp',[]); app.directive(name,fn)
1. 基礎(chǔ)指令
var app=angular.module('myapp',[]); app.run(function($templateCache){ $templateCache.put('cache','<h4>模板內(nèi)容來源于緩存</h4>') }); app.directive('tsHello',function(){ return{ restrict:'EAC', template:'<h4>Hello,directive</h4>' } }) app.directive('tsTplfile',function(){ return{ restrict:'EAC', templateUrl:'/static/tpl.html' } }); app.directive('tsTplscript',function(){ return { restrict:'EAC', templateUrl:'tpl', replace:true } }); //templateUrl屬性值是添加的緩存名稱,加速文件訪問 app.directive('tsTplcache',function(){ return{ restrict:'EAC', templateUrl:'cache' } }) </script>
2. 重要指令
2.1 transclude
<script type="text/ng-template" id='tpl'> <div> <input type="text" ng-model='text' /> <div ng-transclude></div> </div> </script> <ts-tplscript>{{text}}</ts-tplscript> <script type="text/javascript"> var app=angular.module('myapp',[]); app.directive('tsTplscript',function(){ return { restrict:'EAC', templateUrl:'tpl', transclude:true } }); </script>
關(guān)于transclude更加詳細(xì)的介紹,參見另外一篇文章
2.2 link
link屬性的值是一個(gè)函數(shù),在該函數(shù)中可以操控DOM元素的對(duì)象,包括綁定元素的各類事件,定義事件觸發(fā)時(shí)執(zhí)行的內(nèi)容等:
link:function(scope,iEle,iAttrs)
link 函數(shù)包括3個(gè)主要的參數(shù),其中,scope參數(shù)表示指令所在的作用域,它的功能與頁面中控制器注入的作用域是相同的,iEle參數(shù)表示指令中的元素,該元素可以通過Angular內(nèi)部封裝的jqLite進(jìn)行調(diào)用,jqLite相當(dāng)于是一個(gè)壓縮版的jQuery,包含了主要的元素操作API,在語法上與jQuery類似,iAttrs參數(shù)表示指令元素的屬性集合,通過這個(gè)參數(shù)可以獲取元素中的各類屬性。
<script type="text/ng-template" id='tpl'> <button>單擊按鈕</button> </script> <div> <ts-tplscript></ts-tplscript> <div>{{content}}</div> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.directive('tsTplscript',function(){ return { restrict:'EAC', templateUrl:'tpl', replace:true, link:function(scope,iEle,iAttrs){ iEle.bind('click',function(){ scope.$apply(function(){ scope.content='這是點(diǎn)擊后的內(nèi)容'; }) iAttrs.$$element[0].disabled=true;//這里也可以替換為this.disabled=true; }); } } }); </script>
自定義tsTplscript指令時(shí),在指令返回的對(duì)象中添加了link屬性,用于綁定和執(zhí)行DOM元素的各類事件,在屬性值執(zhí)行的函數(shù)中,添加scope,iEle,iAttrs三個(gè)參數(shù),在指令執(zhí)行的過程中,由于指令中并沒有定義scope屬性,因此,scope參數(shù)默認(rèn)就是元素外層父級(jí)scope屬性,即控制器注入的$scope屬性。
此外,iEle參數(shù)就是被指令模板替換后的<button>元素,由于在Angular中引入了jqLite,因此可以直接調(diào)用bind方法綁定元素的各類事件,在執(zhí)行事件函數(shù)的時(shí)候,調(diào)用了scope屬性的$apply方法,它的功能是在執(zhí)行完方法中的函數(shù)之后,重新渲染頁面視圖。
iAttrs參數(shù)是指令元素的屬性集合,$$element則表示與屬性對(duì)應(yīng)的元素集合,該集合是一個(gè)數(shù)組。
2.3 compile
<div ng-controller='myController'> <ts-a> <ts-b> {{tip}} </ts-b> </ts-a> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.controller('myController',function($scope){ $scope.tip='跟蹤compile執(zhí)行過程 '; }); app.directive('tsA',function(){ return { restrict:'EAC', compile:function(tEle,tAttrs,trans){ console.log('正在編譯A指令'); //返回一個(gè)對(duì)象時(shí),對(duì)象中包含兩個(gè)名為`pre`和`post`的方法函數(shù) return { pre:function(scope,iEle,iAttrs){ console.log('正在執(zhí)行A中的pre函數(shù)'); }, post:function(scope,iEle,iAttrs){ console.log('正在執(zhí)行A中的post函數(shù)'); } } } } }); app.directive('tsB',function(){ return { compile:function(tEle,tAttrs,trans){ console.log('正在編譯B指令'); return{ pre:function(scope,iEle,iAttrs){ console.log('正在執(zhí)行B中的pre函數(shù)'); }, post:function(scope,iEle,iAttrs){ console.log('正在執(zhí)行B中的post函數(shù)'); } } } } }) </script>
控制臺(tái)依次輸出:
正在編譯A指令 正在編譯B指令 正在執(zhí)行A中的pre函數(shù) 正在執(zhí)行B中的pre函數(shù) 正在執(zhí)行B中的post函數(shù) 正在執(zhí)行A中的post函數(shù)
2.4 scope
2.4.1 當(dāng)scope值是布爾類型
scope屬性自定義指令時(shí),默認(rèn)值就是布爾類型的,初始值為false,在這種情況下,指令中的作用域就是指令元素所在的作用域,如果scope屬性值為false,表示不創(chuàng)建新的作用域,直接繼承父級(jí)作用域,二者數(shù)據(jù)完全相同,一方有變化,另外一方面將會(huì)自動(dòng)變化。
如果scope屬性值為true,表示子作用域是獨(dú)立創(chuàng)建的,當(dāng)它的內(nèi)容發(fā)生變化時(shí),并不會(huì)修改父作用域中的內(nèi)容,不僅如此,一旦某個(gè)屬性被子作用域進(jìn)行了重置,那么,即使父作用域中的內(nèi)容變化了,子作用域?qū)?yīng)的內(nèi)容也不會(huì)隨之變化。
<script type="text/ng-template" id='tpl'> <div>{{message}}</div> <button ng-transclude></button> </script> <div> <input type="text" ng-model='message' /> <ts-message>固定</ts-message> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.directive('tsMessage',function(){ return { restrict:'EAC', templateUrl:'tpl', transclude:true, scope:true, link:function(scope,iEle,iAttrs){ iEle.bind('click',function(){ scope.$apply(function(){ scope.message='這是單擊按鈕后的值。' }) }) } } }); </script>
在單擊按鈕之前,子作用域中的值隨父作用域改變,當(dāng)單擊按鈕之后,手動(dòng)重置了子作用域中的'message'遍歷,但與變量綁定的父作用域的內(nèi)容并沒有變化,并且子作用域也不再隨父作用域發(fā)生變化。
2.4.2 當(dāng)scope值是對(duì)象
如果將scope屬性值設(shè)置成一個(gè)JSON對(duì)象,那么父作用域與子作用域完全獨(dú)立,不存在任何關(guān)聯(lián)。
當(dāng)指令中的scope屬性值是JSON對(duì)象時(shí),如果子作用域需要添加屬性,必須先添加指令中的link函數(shù),然后通過函數(shù)中的scope對(duì)象進(jìn)行添加,如果在子作用域中,要綁定或調(diào)用父父作用域中的屬性和方法,則需要在scope屬性對(duì)應(yīng)的JSON對(duì)象值中添加綁定策略。
嚴(yán)格來說,在JSON對(duì)象中添加的有3種綁定策略:@ = &
1、@
@綁定與將scope值設(shè)為true,有許多相同的地方,唯一不同之處在于,@綁定在子作用域充值屬性之后,再返回修改父作用域?qū)?yīng)屬性內(nèi)容時(shí),子作用域?qū)?yīng)的屬性,同樣還是會(huì)隨之發(fā)生變化,而使用scope:true,則不會(huì)發(fā)生這一步。
2、=
=綁定的功能是創(chuàng)建一個(gè)父與子作用域可以同時(shí)共享的屬性,即當(dāng)父作用域修改了該屬性,子作用域也隨之變化,反之亦然,兩個(gè)作用域間完全共享和同步。
3、&
&綁定的功能是可以在獨(dú)立的子作用域中直接調(diào)用父作用域的方法,在調(diào)用時(shí)可以向函數(shù)傳遞參數(shù),這種功能的好處在于,避免重復(fù)編寫功能相同的代碼,只需要進(jìn)行簡單的綁定設(shè)置,就可以使指令執(zhí)行后,輕松調(diào)用控制器中的方法。
<script type="text/ng-template" id='tpl'> <div> <span>姓名:{{textName}}</span> <span>年齡:{{textAge}}</span> </div> <button ng-transclude></button> </script> <div ng-controller="myController"> 姓名:<input type="text" ng-model='text_name' /><br> 年齡:<input type="text" ng-model='text_age' /><br> <div>{{tip}}</div> <ts-json a-attr="{{text_name}}" b-attr="text_age" reset="reSet()">重置</ts-json> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.controller('myController',function($scope){ $scope.reSet=function(){ $scope.tip='姓名與年齡重置成功!'; } }); app.directive('tsJson',function(){ return { restrict:'EAC', templateUrl:'tpl', transclude:true, scope:{ textName:'@aAttr', textAge:'=bAttr', reSet:'&reset' }, link:function(scope,iEle,iAttrs){ iEle.bind('click',function(){ scope.$apply(function(){ scope.reSet(); scope.textName='張三'; scope.textAge='20'; }) }) } } }); </script>
綁定的過程:
先在指令元素中創(chuàng)建a-attr或b-attr屬性,由于HTML不區(qū)分大小寫,因此使用-隔開。
需要注意的是:由于在指令中綁定策略不同,在指令元素中,屬性綁定屬性值也會(huì)有些變化,使用@綁定的屬性,綁定屬性值的方式為雙大括號(hào){{}},而使用=綁定的屬性,綁定屬性值的方式為等于號(hào)=,不需要雙大括號(hào).
2.5 require和controller
當(dāng)一個(gè)子元素需要與一個(gè)父元素指令通信時(shí),就需要添加并使用這兩個(gè)屬性值。
<div> <ts-parent> <div>{{ptip}}</div> <ts-child> <div>{{ctip}}</div> </ts-child> <button ng-click='click()'>換位</button> </ts-parent> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.directive('tsParent',function(){ return { restrict:'EAC', controller:function($scope,$compile,$http){ this.addChild=function(c){ $scope.ptip='今天天氣不錯(cuò)!'; $scope.click=function(){ $scope.tmp=$scope.ptip; $scope.ptip=c.ctip; c.ctip=$scope.tmp; } } } } }); app.directive('tsChild',function(){ return { restrict:'EAC', require:'^?tsParent', link:function(scope,iEle,iAttrs,ctrl){ scope.ctip='氣溫正好18攝氏度'; ctrl.addChild(scope); } } }) </script>
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。