详解angular 中的自定义指令之详解API!
自定义属性的四种类别
分为:元素E,属性A,注释M,类C,分别如下:
简单创建一个指令
html结构:
JavaScript结构:
angular.module('myApp',[])
.controller('myCtrl',['$scope',function($scope){
$scope.customer={
name:'Naomi',
address:'1600Amphitheatre'
};
}])
.directive('myCustomer',function(){
return{
template:'Name:{{customer.name}}Address:{{customer.address}}'
};
});
输出:
Name:NaomiAddress:1600Amphitheatre
说明:此处,myCtrl中定义的$scope.customer属性和属性值都在指令中的模板使用了。同样的,在指令return对象中的template也可被替换成一路径,在路径html中书写和template中同样的代码,使用这种方式,可以操作更多代码。
templateUrl函数式编程
html结构:
javascript结构:
angular.module('myApp',[])
.controller('myCtrl',['$scope',function($scope){
$scope.customer={
name:'Naomi',
address:'1600Amphitheatre'
};
}])
.directive('myCustomer',function(){
return{
templateUrl:function(elem,attr){
return'customer-'+attr.type+'.html';
}
};
});
不同的templateUrl①
Name:{{customer.name}}
不同的templateUrl②
Address:{{customer.address}}
输出结果:
Name:Naomi
Address:1600Amphitheatre
说明:templateUrl的值可以是一个函数返回值,返回用于指令中的html模板的url。
隔离指令的作用域
①通过不同的controller
html结构:
javascript结构:
angular.module('myApp',[])
.controller('myCtrl1',['$scope',function($scope){
$scope.customer={
name:'Naomi',
address:'1600Amphitheatre'
};
}])
.controller('myCtrl2',['$scope',function($scope){
$scope.customer={
name:'Igor',
address:'123Somewhere'
};
}])
.directive('myCustomer',function(){
return{
restrict:'E',
templateUrl:'my-customer.html'
};
});
templateUrlhtml结构:
Name:{{customer.name}}Address:{{customer.address}}
输出结果:
Name:NaomiAddress:1600Amphitheatre
Name:IgorAddress:123Somewhere
说明:可见不同的controller有不同的作用范围。虽然指令一样,每次渲染都是分离的,所以我们可以抽象出来指令,用于html模板和代码的重用,封装。但是这样又不是很好,因为用了两个controller,我们可以使用指令中的scope而不是controller里的scope来替代,具体做法是将外部的scope映射到指令内部的scope,如下:
②通过指令属性映射scope
html结构:
javascript结构:
angular.module('myApp',[])
.controller('myCtrl',['$scope',function($scope){
$scope.naomi={name:'Naomi',address:'1600Amphitheatre'};
$scope.igor={name:'Igor',address:'123Somewhere'};
}])
.directive('myCustomer',function(){
return{
restrict:'E',
scope:{
customerInfo:'=info'
},
templateUrl:'my-customer-iso.html'
};
});
templateUrlhtml结构:
Name:{{customerInfo.name}}Address:{{customerInfo.address}}
编译后的html结果:
Name:NaomiAddress:1600Amphitheatre
Name:IgorAddress:123Somewhere
③指令中的如果定义scope属性则html中的scope不会直接继承controller中的scope,在html中使用的都需要在scope:{}中声明,否则就是undefined
html结构:
javascript结构:
angular.module('myApp',[])
.controller('myCtrl',['$scope',function($scope){
$scope.naomi={name:'Naomi',address:'1600Amphitheatre'};
$scope.vojta={name:'Vojta',address:'3456SomewhereElse'};
}])
.directive('myCustomer',function(){
return{
restrict:'E',
scope:{
customerInfo:'=info'
},
templateUrl:'my-customer-plus-vojta.html'
};
});
templateUrlhtml结构:
Name:{{customerInfo.name}}Address:{{customerInfo.address}}
Name:{{vojta.name}}Address:{{vojta.address}}
html编译后的结果:
Name:NaomiAddress:1600Amphitheatre
Name:Address:
说明:vojta在指令中的scope没有被定义,不会直接继承在controller中的,那么他就是undefined,所以就是空白(什么都不显示)
可操作DOM的指令
创建一个用于操作dom的指令,如果需要dom操作也都应该放在指令里。
html结构:
Dateformat:
Currenttimeis:
javascript结构:
angular.module('myApp',[])
.controller('myCtrl',['$scope',function($scope){
$scope.format='M/d/yyh:mm:ssa';
}])
.directive('myCurrentTime',function($interval,dateFilter){
return{
restrict:'AE',
link:function(scope,element,attr){
varformat,timeoutId;
/*更新时间函数*/
functionupdateTime(){
element.text(dateFilter(newDate(),format));
}
/*监视时间格式的改变*/
varattrWatch=scope.$watch(attrs.myCurrentTime,function(value){
format=value;
updateTime();
});
/*定时器*/
timeoutId=$interval(function(){
updateTime();//updateDOM
},1000);
/*页面跳转后移除定时器防止内存泄露*/
element.on('$destroy',function(){
$interval.cancel(timeoutId);
attrWatch();//移除watch
});
}
};
});
说明:在link函数中,操作dom节点,让dom的文本节点动态显示时间跳动。在页面跳转之后及时清除定时器和监视器以免发生内存泄漏。
通过transclude和ng-transclude创建可包裹其他元素的指令
html结构:
Checkoutthecontents,{{name}}!
javascript结构:
angular.module('myApp',[])
.controller('myCtrl',['$scope',function($scope){
$scope.name='Tobias';
}])
.directive('myDialog',function(){
return{
restrict:'E',
transclude:true,
scope:{},
templateUrl:'my-dialog.html',
link:function(scope){
scope.name='Jeff';
}
};
});
templateUrlhtml结构:
编译后的html结构:
Checkoutthecontents,Tobias!
说明:指令中的scope本应隔离controller中的作用域的,但是由于设置了transclude=true选项,scope就会继承controller中的定义,所以最终是Tobias而不是Jeff。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。