自定义指令:
directive (1)restrict 创建的A E C M 区分大小写,都要大写 (2)replace true和false (3)template 模板 (4)templateUrl 模板的链接地址
var m1 = angular.module('myApp',[]);
m1.directive('hello',function(){
return {
restrict : 'AECM', // A 属性 E 标签 C class的用法 M 解析注释,但是要和replace :true一起使用
template : '<div>明天你好</div>',
replace : true
}
})
<hello></hello> // E 标签(没有replace:true) 页面显示<hello><div>明天你好</div></hello>
<div hello></div> // A 属性(没有replace:true) 页面显示<div hello><div>明天你好</div></div>
<div class="hello"></div> // C class用法(没有replace:true)页面显示<div class="hello"><div>明天你好</div></div>
<!-- directive:hello --> // M 解析注释 (必须要写replace:true)页面显示<div>明天你好</div>
自定义的指令是可以复用的,不能复用的就不叫指令了
关于directive的具体参数,注意 template的 书写位置,不可以调换template或者templateUrl的位置
m1.directive('myHello',function(){
return {
restrict : 'E', // 设置了一个 <my-hello></my-hello> 的标签
replace : true, // 新的模板会把 <my-hello></my-hello> 的标签代替
scope : {
// {} 隔离作用域,不会向外部找数据
// scope : true 是独立作用域,不受到其他影响
myId : '@', // @ 绑定策略,就是绑定普通的字符串
myName : '=', // = 绑定父级下的变量
myFn : '&' // & 绑定父级下的函数
},
controller : ['$scope',function($scope){
// 针对自定义属性而设置的,里面的数据共享
$scope.name = "hello";
}],
template(模板) : '<div class="box" id={{myId}}">\ // 给每个div绑定不同的id
<input type="button" value="1" class="active">\
<input type="button" value="2" ng-click="myFn({num:888})">\ // 在父级作用域中找函数,并且传入参数
<input type="button" value="3">\
<div class="show">{{myName}}</div>\ // 每个div中的内容是父级作用域中找的
<div>22222</div>\
<div>33333</div>\
</div>'
}
});
<my-hello my-id = "box1" my-name="name" my-fn="B(num)"></my-hello> // 给函数传参
<my-hello my-id = "box2" my-name="name" my-fn="B(num)"></my-hello>
选项卡案例:
css
<style>
input.active{background: red;}
.box div{width:400px;height: 200px;border:1px solid #000;display: none;margin-top:20px;}
.box div.show{display: block;}
</style>
JavaScript(需要引入jQuery文件)<script>
var m1 = angular.module('myApp',[]);
m1.directive('myHello',function(){
return {
restrict : 'E',
replace : true,
scope : {
myId : '@',
myData : '=',
},
controller : ['$scope',function($scope){
$scope.name = "hello";
}],
template : '<div class="box" id={{myId}}">\
<input ng-repeat = "data in myData" type="button" value="{{ data.title}}" ng-class="{active:$first}">\
<div ng-repeat = "data in myData" ng-class="{show:$first}">{{data.content}}</div>\
</div>',
link :function(scope,element,attr){ // link要写在template后面 并且有三个参数
console.log(scope.name); // 找到scope下的属性 就是hello
console.log(element); // 找到两个div
console.log(attr.myId); // 每个div下的属性 attr.myId就代表打印的是每个div的id
element.delegate('input','click',function(){ // delegate 事件委托
$(this).attr('class','active').siblings('input').attr('class','');
$(this).siblings('div').eq($(this).index()).attr('class','show').siblings('div').attr('class','');
})
}
}
});
m1.controller('A',['$scope',function($scope){
$scope.name = 'hi';
$scope.dataList1 = [
{ title:'导航一' , content : '我是导航一'},
{ title:'导航二' , content : '我是导航二'},
{ title:'导航三' , content : '我是导航三'}
];
$scope.dataList2 = [
{ title:'二组 导航一' , content : '我是二组导航一'},
{ title:'二组 导航二' , content : '我是二组导航二'},
];
}])
</script>
html
<body ng-controller="A">
<my-hello my-id = "box1" my-data="dataList1"></my-hello>
<my-hello my-id = "box2" my-data="dataList2"></my-hello>
</body>
自定义拖拽指令(主要完成的就是当my-drag= false时,完成普通拖拽,当my-drag = true时,完成带边框的拖拽)
要完成拖拽指令的元素,需要绝对定位
var m1 = angular.module('myApp',[]);
m1.directive('myDrag',function(){
return {
restrict : 'A',
link :function(scope,element,attr){
var disX = 0;
var disY = 0;
// attr.myDrag 本应返回的类型是string,angular.equals将string类型转化为Boolean类型
attr.myDrag = angular.equals(attr.myDrag,'true');
element.on('mousedown',function(ev){
var This = this;
disX = ev.pageX - $(this).offset().left;
disY = ev.pageY - $(this).offset().top;
if(attr.myDrag){
var $line = $('<div>');
$line.css({width:$(this).outerWidth(),heigth:$(this).outerHeight,position:'absolute',left:$(this).offset().left-1,top:$(this).offset().top-1,border : '1px dashed #000',background : 'none'});
$('body').append($line);
}
$(document).on('mousemove',function(ev){
if(attr.myDrag){
$($line).css({'left':ev.pageX - disX-1, 'top':ev.pageY - disY-1});
}else{
$(This).css({'left':ev.pageX - disX, 'top':ev.pageY - disY});
}
});
$(document).on('mouseup',function(){
if(attr.myDrag){
$(This).css({'left':$line.offset().left+1, 'top':$line.offset().top+1});
$line.remove();
}
$(document).off();
});
return false;
})
}
}
});
<div my-drag="false"></div> // 完成的就是不带边框的拖拽
指令与指令的嵌套
var m1 = angular.module('myApp',[]);
m1.directive('hello',function(){
return {
restrict : 'E',
replace : true,
transclude : true, // 默认的情况下是false,变成true以后,指令就可以嵌套指令了,在template中写
controller : function($scope){
this.name = "replace"; // 看成对象的方式,在其他指令中也可以找到这个对象下的属性
},
template : '<div ng-transclude>hello word<h1></h1></div>' // ng-transclude 指令嵌套指令,
//<div>hello word<h1 ng-transclude></h1></div> 显示的结果就是<div>hello word<h1 ng-transclude><strong>hi word</strong></h1></div>
//<div ng-transclude>hello word<h1></h1></div> 显示结果就是<div ng-transclude><strong>hi word</strong></div>
}
});
m1.directive('hi',function(){
return {
restrict : 'E',
replace : true,
require : "?^hello", // ?容错处理,找不到不会报错,返回一个undefined ^ 寻找得个指令的父级,一般和?连用
template : '<strong>hi word</strong>',
link : function(scope,element,attr,reController){
console.log(reController.name); // reController 所要依赖的controller
}
}
});
<hello>
<hi></hi>
</hello> // 最后的页面显示就是 加粗的hi word