一、指令的职责
指令的职责是修改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的一个函数,稍后调用。

浙公网安备 33010602011771号