angular directive

强大的工具来操 作和修改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

js code 
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值