AngularJS 指令
指令是angularjs的核心概念之一,它相当于一个自定义的HTML元素,在Angular官方文档中称它为HTML语言的DSL(特定领域语言)扩展。
根据使用场景和作用,指令可分为组件型指令和装饰器性指令。
组件型指令主要是为了将复杂而庞大的Viewfenli,使得页面的View具有更强的可读性和维护性,是实现“高内聚低耦合”和“分离关注点”的有效手段;
而装饰器型指令是为了给DOM添加行为,时期具有某种能力,如自动聚焦,双向绑定,可点击等能力,同时它还是链接Model和View之间的桥梁,保持View和Model的同步。
理解两种指令的用途非常重要,他们在写法,业务含义和使用范围等方面都有非常明显的区别,理解了它们,对于我们日常的指令开发具有很好的指导作用。
组件型指令
组件型指令应是一个小型的,自封装和内聚的整体,它包含业务所需要显示的视图和交互逻辑。
<span style="font-size:12px;">angular.module('myApp', []).
directive('myDirective',function(){
return {
restrict: 'EA',//用作HTML元素
scope:{<span style="white-space:pre"> </span></span><pre name="code" class="javascript"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre"> </span>//使用独立作用域</span>
}controller:fucntion ($scope){
//声明指令的控制器,用于初始化指令},templateUrl:'test.html',//指定模板 } })
A: attribute属性:当做属性来使用
E:element元素:当做标签元素来使用
C:class类:当做CSS样式来使用
M:comments注释:当做注释使用
对于组件型指令,标准用法是E,但是为了兼容IE8,通常也支持一个A,因为IE8的自定义元素需要先用document.createElement注册,用A可以省去注册的麻烦。
-scope用于定义该指令的作用域。默认为false,此时这个指令不会有新的作用域,它会直接访问现有作用域上的属性或方法,也可以不访问作用域。如果同一节点上有新作用域或独立作用域指令,则直接使用它,否则直接使用父级作用域。
通常为了实现更好的指令封装即”低耦合“,我们需要给指令一个独立作用域,即不能设置成false。
scope的值可以设置成一个哈希对象:
scope:{
name:'@',
details:'=',
onUpdate:'&'
}
以<my-directive name='test' details='details' on-update='updateIt(times)'></user-details>为例,name的值将被绑定为字符串test,而details的值将绑定到付页面scope上一个名为details的变量,而onUpdate绑定的则是一个回调函数,它是父页面scope上一个名为updateIt的函数。
对于组件型指令,我们侧重与内容信息的展示,所以一般不涉及link函数,而应该尽量地将业务逻辑放置在controller中。
装饰器型指令
组件型注重于信息展示和业务逻辑控制。而 装饰器型指令主要用于给dom添加行为和保持View和Model的同步,也因此restrict的值通常为设置为'A',这也符合装饰器型指令的语义--装饰,装饰器型指令不是一个主体,而是给一个主题附加功能的连接器。在装饰器型指令中,我们经常需要进行DOM操作,而DOM操作则写在link函数中。装饰器型指令的定义方式如下:
angular.module('myApp', []).
directive('myDirective',function(){
return {
restrict: 'A',
scope:{
}
link:fucntion myDirectiveCtrl(scope. elem, attrs){
},
}
})
有时候,多个装饰器会被用于同一个指令,包括独立作用于指令,所以装饰器型指令通常不使用新作用域或独立作用域。在这种情况下,我们可以通过attrs来访问绑定的属性,仍然是上面那个例子, <my-directive name='test' details='details' on-update='updateIt(times)'></user-details>
对于=型的绑定,我们可以通过scope.$eval取到它:scope.$eval(attrs.details)等价于details:'='
对于&型的绑定,则可以这样,scope.$eval(attrs.onUpdate, {times:3})