Una

接下来的日子,陆续把未总结的问题补充起来......

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

一、指令的职责

  指令的职责是修改DOM结构,并将作用域和DOM连接起来.即指令既要操作DOM,将作用域内的数据绑定到DOM节点上,又要为DOM绑定事件调用作用域内的对应的方法。

 

二、创建自定义指令

调用自定义指令的4种方式:元素、属性、样式类、注释.

常用的是前两种,实例如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body ng-app="myApp" >
		<hello></hello><!--E元素-->
		<div hello></div><!--A属性-->
		<div class="hello"></div><!--C样式类-->
		<!--directive:hello--> 
		
	</body>
	<script type="text/javascript" src="js/angular.js" ></script>
    <script type="text/javascript" src="js/directive.js" ></script>
</html>

 js代码:

var app = angular.module("myApp",[]);
app.directive("hello",function(){
	return {
		restrict: 'AECM',
		template:'<div>Hi everyone</div>',//模板
		//templateUrl:'index.html',
		replace: true
	}
});

 

测试结果只有3条内容,没有显示采用注释的方法调用指令的结果.不过常用的还是使用属性和元素的方式来调用指令.

 

三、指令定义中用到的其他字段

1.templateUrl

模板的显示还可以使用templateUrl属性来调用html文件中的DOM元素.

 

如果其他指令也要使用同一个模板,可以利用AngularJs中的$templateCache属性将模板缓存起来然后再调用:

用到angular中的run方法,它只会执行一次.

js文件:

var app = angular.module("myApp",[]);
//app.directive("hello",function(){
//	return {
//		restrict: 'AECM',
//		template:'<div>Hi everyone</div>',//模板
//		//templateUrl:'index.html',
//		replace: true
//	}
//});

app.run(function($templateCache){
	$templateCache.put("hello.html","<div>Hello,my name is yo</div>");
});

app.directive("hello",function($templateCache){
	return {
		restrict: 'A',
		//template:'<div>Hi everyone</div>',//模板
		template:$templateCache.get("hello.html"),//模板
		//templateUrl:'index.html',
		replace: true
	}
});

app.directive("hi",function($templateCache){
	return {
		restrict: 'E',
		//template:'<div>Hi everyone</div>',//模板
		template:$templateCache.get("hello.html"),//模板
		//templateUrl:'index.html',
		replace: true
	}
});

 测试结果:

2.transclude:是否为指令模板或编译函数提供指令元素中的内容.

不加这个字段,在指令中添加模板会替换掉之前有的内容,transclude是很重要的一个字段,它可以让指令与指令之间相互嵌套.

js关键代码:

效果:

 

3. link:定义将指令与作用域连接起来的链接函数

a)控制器与指令的交互:

js文件:

var app = angular.module("myApp",[]);
app.controller("myController",['$scope',function($scope){
	$scope.loadData = function() {
		console.log("数据加载中...");
	};
}
]);

app.directive("loader",function($templateCache){
	return {
		restrict: 'AE',
		link: function(scope,element,attr){
			element.bind("mouseenter",function(){
				scope.loadData();
			});
		}
		//template:'<div>Hi everyone</div>',//模板
		//transclude: true,
		//template:"<div>Hi everyone<div ng-transclude></div></div>",
		//templateUrl:'index.html',
			
	}
});

 效果:

注:将scope.loadData();替换成scope.$apply("loadData()");可以达到同样的效果.

 

如果有多个controller指令的情况,如何调用方法?

采用用属性的方式来调用指令:

var app = angular.module("myApp",[]);
app.controller("myController",['$scope',function($scope){
	$scope.loadData = function() {
		console.log("数据加载中...");
	};
}
]);

app.controller("myController2",['$scope',function($scope){
	$scope.loadData2 = function() {
		console.log("数据加载中aaaa...");
	};
}
]);


app.directive("loader",function($templateCache){
	return {
		restrict: 'AE',
		link:function(scope,element,attrs){
			element.bind("mouseenter",function(){
				//scope.loadData();
				scope.$apply(attrs.howtoload);
			});
		}
		//template:'<div>Hi everyone</div>',//模板
		//transclude: true,
		//template:"<div>Hi everyone<div ng-transclude></div></div>",
		//templateUrl:'index.html',
			
	}
});

//b)指令与指令交互
var app = angular.module("myApp",[]); app.directive("superman",function() { return { scope: {},//创建独立作用域 restrict:'AE', controller: function($scope){//一个作为指令控制器的函数,相当于一个public方法,让外部去调用 $scope.abilities = []; this.addStrength = function(){ $scope.abilities.push("strength"); }; this.addSpeed = function(){ $scope.abilities.push("speed"); }; this.addLight = function(){ $scope.abilities.push("Light"); }; }, link: function(scope,element,attrs){//处理指令内部的元素 element.bind("mouseenter",function(){ console.log(scope.abilities); }); } } }); app.directive("strength",function(){ return { require:'^superman',//当前指令依赖superman link: function(scope,element,attrs,supermanCtrl){ supermanCtrl.addStrength(); } } }); app.directive("speed",function(){ return { require:'^superman',//当前指令依赖superman link: function(scope,element,attrs,supermanCtrl){ supermanCtrl.addSpeed(); } } }); app.directive("light",function(){ return { require:'^superman',//当前指令依赖superman link: function(scope,element,attrs,supermanCtrl){ supermanCtrl.addLight(); } } });

 

测试结果:



 

4.scope:为指令创建一个新的子作用域,还是创建一个独立作用域

实例:

var app = angular.module("myApp",[]);
app.directive("hello",function(){
	return {
		restrict:'AE',
		template:'<div><input type="text" ng-model="name">{{name}}</div>'
	}
});

可以看到四个input的作用域不是独立的,改变其中一个input中的值,其他三个也会一起被改变.

添加scope后的结果:

 

scope的三种绑定:@ = &

实例:

js代码:

测试结果:

 

用scope代替link的写法:

1)@

模板中加一个表单:

var app = angular.module("myApp",[]);
app.controller("MyCtrl",function($scope){
	$scope.ctrlfriendname = "王宝强";
});
app.directive("hello",function(){
	return {
		restrict:'AE',
		scope:{
			friendname:'@'
		},
		template:'<div><input type="text" ng-model="friendname">{{friendname}}</div>'
//		link: function(scope,element,attrs){
//			scope.friendname=attrs.friendname;
//		}
		
	}
});

 测试结果:

 

改变表单中的值如下:

 

2)=

实例:

js文件:

测试结果:

3)&

实例:

 

js代码:

 

 测试结果:

点击按钮:

 

总结:@是把当前属性作为字符串传递,=是与父scope中的属性进行双向绑定,&是传递来自父scope的一个函数,稍后调用。

 

posted on 2016-08-20 22:38  youyi2016  阅读(349)  评论(0编辑  收藏  举报