强大的工具来操 作和修改DOM
本来没想把directive写成一章的,但是发现内容越来越多~只能单拿出来拉,hiahia
template
使用方式如下,其中restrict可以分为E(element),A(attribute,如果不声明restrict,默认是A),C(Class) & M(comment 在html中的使用方式<!-- directive: hello-->)
appModule.directive('hello', function() {
return {
restrict: 'E',
template: '<div>Hi there</div>',
replace: true
};
});
当然了,除了可以动态修改和操作Dom,directive另外一个好处,和service一样,作为一个公共的组件,可以让多个controller共用
knowledge
directive存在的背后,是一个叫做$compile的服务
www.tuicool.com/articles/yMZzmm
Compiler作为Angular的一个服务(Service),负责遍历DOM结构,寻找属性。编译过程分成两个阶段:
1. 编译(Compile):遍历DOM节点树,收集所有directives。返回结果是一个链接函数(linking function)。
2. 链接(Link):将directives绑定到一个作用域(scope)中,创建一个实况视图(live view)。在scope中的任何改变,将会在视图中得到体现(更新视图);任何用户对模版的活动(改变),将会体现在scope model中(双向绑定)。这使得scope model能够反映正确的值。
一些directives,诸如ng-repeat,会为每一个在集合(collection)中的元素复制一次特定的元素(组合)。编译和链接两个阶段,使性能得以提升。因为克隆出来的模版(template)只需要编译一次,然后为每一个集合中的元素进行一次链接(类似模版缓存)。
behavior
所以,directive除了绑定上面例子中template,还可以提供behavior,即function,一般是link:function,这种方式可以直接去掉link字段简写为function
这里的link和上面的link的区别,请参考上面链接。
scope
只有定义了scope,哪怕为空,也可以避免掉同一个directive同一个作用域,修改一个,其他全变的问题~
scope有几个修饰符
”=“:指令中的属性取值为controller中对应$scope上属性的取值,可用于双向数据的绑定
”@“:指令中的取值为html中的字面量/直接量;建立一个local scope property到DOM属性的绑定。因为属性值总是String类型,所以这个值总是返回一个字符串。如果没有通过@attr指定属性名称,那么本地名称将与DOM属性的名称一直。例如,widget的scope定义为:{localName:’@myAttr’}。那么,widget scope property的localName会映射出”hello {{name}}"转换后的真实值。name属性值改变后,widget scope的localName属性也会相应地改变(仅仅单向,与下面的”=”不同)。
”&“:指令中的取值为Contoller中对应$scope上的属性,但是这属性必须为一个函数回调。
directive communication
directive之间的交互,请看下面例子
var myapp=angular.module("myapp",[]);
myapp.directive("superhero",function(){
return {
restrict: "E",
scope : {},
controller: function($scope){
$scope.abilities=[]
this.addStrength = function(){
$scope.abilities.push('strength');
}
this.addSpeed = function(){
$scope.abilities.push('speed');
}
this.addFlight = function(){
$scope.abilities.push('flight');
}
},
link: function( scope, element, attrs ) {
element.addClass("panel");
element.bind( "mouseenter", function() {
console.log(scope.abilities);
});
}
}
});
myapp.directive("speed",function(){
return {
require: "superhero",
link:function(scope,element,attrs,superheroCtrl){
superheroCtrl.addSpeed()
}
}
});
angular.element / compile
前面介绍了behavior,这里介绍一下complile,我们知道,一般compile做的事情是遍历整个html,将directive收集起来,返回一个链接函数。一般情况都不需要complile,什么时候需要呢?
var myapp=angular.module("myapp",[]);
myapp.directive("dumbPassword",function(){
return{
restrict:"E",
replace: true,
template:"<div><input type=\"text\" ng_model=\"model.input\"><div>{{model.input}}</div></div>",
link:function(scope,element){
scope.$watch("model.input",function(value){
if(value==="password"){
element.children(1).toggleClass("main");
}});
}}})
如果想要操作dom中的元素,在angular js中没有jquery的findelement类似的元素,只能通过上面的element.children(1)查找,这种方法使得代码变得死板而且不好维护。
这时候就需要引入angular.element,reference一个element,以后对此element进行操作即可;
var myapp=angular.module("myapp",[]);
myapp.directive("dumbPassword",function(){
var validElement = angular.element("<div>{{model.input}}</div>");
return{
restrict:"E",
replace: true,
template:"<div><input type=\"text\" ng_model=\"model.input\"></div>",
compile: function(tElem){
tElem.append(validElement);
return function(scope){
scope.$watch("model.input",function(value){
if(value==="password"){
validElement.toggleClass("main");}
});
}
}
}
})
zippy example
var myapp=angular.module("myapp",[]);
myapp.directive("zippy",function(){
return{
restrict:"E",
transclude:true,
scope:{
title:"@",
},
template:'<div><h3 ng-click="toggleContent()">{{title}}</h3><div ng-show="isContentVisible" ng-transclude>Hello World</div></div>',
link:function(scope,element,attrs){
scope.isContentVisible=false;
scope.toggleContent=function(){
scope.isContentVisible=!scope.isContentVisible;
}
}
}
})
html
<div ng-app="myapp">
<input type="text" ng-model="model.title">
<input type="text" ng-model="model.content">
<zippy title="{{model.title}}">
This is the {{model.content}}
</zippy>
</div>
template url
为啥把template url放到最后讲呢~没啥原因,就是想要复用一下上面的zippy的例子拉~
其实就是将directive中template写到html中,两种办法,第一
js改动template那段改成templateurl: "zippy.html"
html中的改动
<script type="text/ng-template" id="zippy.html">
<div>
<h3 ng-click="toggleContent()">{{title}}</h3>
<div ng-show="isContentVisible" ng-transclude>Hello World</div>
</div>
</script>
和上面的zippy例子一样哒效果~
第二,直接把那段html代码存到zippy.html中就行了
http://www.cnblogs.com/lcllao/archive/2012/09/04/2669802.html