版本:1.5.7
创建自定义指令的原型如下:
angular.module("xxx", []).directive("xx", function() {
return {
restrict: "A",
scope: {
},
template: "",
transclude: true,
link: function(scope, element, attrs) {
}
}
})
下面对指令对象中的各个属性逐一解释:
- restrict,指令声明的形式,有4中: A/E/C/M,A代表在标签属性中声明,E代表使用标签声明,C代表在class属性中声明,M代表在注释中声明
- scope,当不声明scope的时候,指令共享外部控制器中的scope,当定义了scope的时候使用指令自己独立的scope,从"高内聚 低耦合"的角度来看,大部分自定义指令的时候都需要自定义scope。虽然自定义的scope是独立的,但是angular框架仍然提供了与外部scope交互的接口:
其中"="的作用,是将scope中的config对象暴露给外部scope,实现了双向绑定,"="后面也可以自定义外部参数的名称,默认"=config";@绑定字符串变量(没用过);&绑定函数,用户可以将自己创建的函数绑定到指令中&指定的函数上,当用户调用cb函数的时候会触发用户外部绑定的函数。scope:{ config:"=", id:"@", cb:"&" }
- template,模板内容,可以用templateUrl代替
- transclude,默认值是false,当声明该属性的时候该值必须是true,如果声明了改属性,会将指令标签的内容填充到模板中ng-transclude指令所在的标签中。
- link:用来将模板中的内容生成最终DOM的函数,element指的是指令所在的标签对象(DOM对象),attrs指的是指令所在的标签属性是个MAP对象,它和compile函数的区别是compile函数处理的是模板内容,这些内容还未加载到DOM中,link函数处理的内容已经是DOM对象了。
指令开发中要注意的几点技巧:
- 当link中使用了第三方的异步回掉的时候,回掉函数的数据无法写入到scope中,这个时候要用$apply函数将回掉函数的上下去应用到当前scope.
scope.$apply(function(){ scope.xxx = xx; });
- scope中的M改变了,但是V没有随之变化,举例:
当yyy变化的时候xxx,不会随之变化,这个时候要用$watch函数,template:"<div>{{xxx}}<div>" /******************************/ link:function(scope,element,attrs){ scope.xxx = function(){ return scope.yyy+1; } } /******************************/ scope.yyy = 1;
scope.$watch("yyy",function(newVal,oldV)){ scope.xxx = newVal+1; }
- 多controller间的通讯,需要定义个父controller,子controller通过$emit发送事件,父controller通过$on接收事件,然手通过$broadcase向所有的子controller广播时间,子controller通过$on接收