定义一个指令的方法非常简单,只需要调用`directive`方法即可:
var app=angular.module('myapp',[]); app.directive(name,fn)
1. 基础指令
var app=angular.module('myapp',[]); app.run(function($templateCache){ $templateCache.put('cache','<h3>模板内容来源于缓存</h3>') }); app.directive('tsHello',function(){ return{ restrict:'EAC', template:'<h3>Hello,directive</h3>' } }) 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"> <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>
关于transclude更加详细的介绍,参见另外一篇文章
2.2 link
link属性的值是一个函数,在该函数中可以操控DOM元素的对象,包括绑定元素的各类事件,定义事件触发时执行的内容等:
link:function(scope,iEle,iAttrs)
link 函数包括3个主要的参数,其中,scope参数表示指令所在的作用域,它的功能与页面中控制器注入的作用域是相同的,iEle参数表示指令中的元素,该元素可以通过Angular内部封装的jqLite进行调用,jqLite相当于是一个压缩版的jQuery,包含了主要的元素操作API,在语法上与jQuery类似,iAttrs参数表示指令元素的属性集合,通过这个参数可以获取元素中的各类属性。
<script type="text/ng-template"> <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='这是点击后的内容'; }) iAttrs.$$element[0].disabled=true;//这里也可以替换为this.disabled=true; }); } } }); </script>
自定义tsTplscript指令时,在指令返回的对象中添加了link属性,用于绑定和执行DOM元素的各类事件,在属性值执行的函数中,添加scope,iEle,iAttrs三个参数,在指令执行的过程中,由于指令中并没有定义scope属性,因此,scope参数默认就是元素外层父级scope属性,即控制器注入的$scope属性。
此外,iEle参数就是被指令模板替换后的<button>元素,由于在Angular中引入了jqLite,因此可以直接调用bind方法绑定元素的各类事件,在执行事件函数的时候,调用了scope属性的$apply方法,它的功能是在执行完方法中的函数之后,重新渲染页面视图。
iAttrs参数是指令元素的属性集合,$$element则表示与属性对应的元素集合,该集合是一个数组。
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执行过程 '; }); app.directive('tsA',function(){ return { restrict:'EAC', compile:function(tEle,tAttrs,trans){ console.log('正在编译A指令'); //返回一个对象时,对象中包含两个名为`pre`和`post`的方法函数 return { pre:function(scope,iEle,iAttrs){ console.log('正在执行A中的pre函数'); }, post:function(scope,iEle,iAttrs){ console.log('正在执行A中的post函数'); } } } } }); app.directive('tsB',function(){ return { compile:function(tEle,tAttrs,trans){ console.log('正在编译B指令'); return{ pre:function(scope,iEle,iAttrs){ console.log('正在执行B中的pre函数'); }, post:function(scope,iEle,iAttrs){ console.log('正在执行B中的post函数'); } } } } }) </script>
控制台依次输出:
正在编译A指令 正在编译B指令 正在执行A中的pre函数 正在执行B中的pre函数 正在执行B中的post函数 正在执行A中的post函数
2.4 scope
2.4.1 当scope值是布尔类型