自定义指令
angularjs中有很多内置指令,一般都是以ng开头的;比如:ng-app,ng-click,ng-repeat等等。本文介绍angularjs的自定义指令的用法。
指令的定义
首先在html标签处设置ng-app的属性值,然后在js文件中就可以调用angular.module得到一个module,最后就可以用module.directive定义一个指令。代码如下:
html文件
<!DOCTYPE html> <html ng-app="directive"> <head lang="en"> <Meta charset="UTF-8"> <title>directive</title> <script src="../bower_components/angular/angular.min.js"></script> <script src="./directive.js"></script> </head> <body> <div my-directive></div> </body> </html>
js文件
var app = angular.module('directive',[]); app.directive('myDirective',function(){ return { restrict:"A",require:true,template:"<span>hello angular</span>",}; });
这个例子只使用了directive的最简单的参数配置,下面是一个详细的参数配置列表
app.directive('myDirective',function factory(injectables) { return { restrict: string,//指令的使用方式,包括标签,属性,类,注释 priority: number,//指令执行的优先级 template: string,//指令使用的模板,用HTML字符串的形式表示 templateUrl: string,//从指定的URL地址加载模板 replace: bool,//是否用模板替换当前元素,若为false,则append在当前元素上 transclude: bool,//是否将当前元素的内容转移到模板中 scope: bool or object,//指定指令的作用域 controller: function controllerConstructor($scope,$element,$attrs,$transclude){...},//定义与其他指令进行交互的接口函数 require: string,//指定需要依赖的其他指令 link: function postLink(scope,iElement,iAttrs) {...},//以编程的方式操作DOM,包括添加监听器等 compile: function compile(tElement,tAttrs,transclude){ return: { pre: function preLink(scope,iAttrs,controller){...},post: function postLink(scope,controller){...} } } }; });
下面介绍几个常用的参数
restrict
四个值"A","E","C","M",分别代码属性,标签,类,注释,如下:
restrict:"A" <div my-directive></div> restrict:"E" <my-directive></my-directive> restrict:"C" <div class="my-diretive"></div> restrict:"M" <!--directive:my-directive-->
只测试了A和E的值,感兴趣的朋友可以测试一下其他。
template 和 templateUrl
这两个参数只需要设置一个就行。
transclude
该参数的意思是替换指令的内容,更改上面的例子。html更改部分
<div my-directive>hello angular</div>
js更改部分
app.directive('myDirective',function(){ return { restrict:"A",transclude:true,//增加transclude参数的设置 template:"<div><span ng-transclude></span></div>",//将指令的内容替换到span标签下 }; });
scope
false 默认值。使用父作用域作为自己的作用域 true 新建一个作用域,该作用域继承父作用域 javascript对象
当scope为javascript对象时,键值对的形式定义。直接看例子吧!
html:
<!DOCTYPE html> <html ng-app="directive"> <head lang="en"> <Meta charset="UTF-8"> <title>directive</title> <script src="../bower_components/angular/angular.min.js"></script> <script src="./directive.js"></script> </head> <body> <div ng-controller="directive"> <div my-directive etitle="title">{{text}}</div> </div> </body> </html>
js:
var app = angular.module('directive',function(){ return { restrict:'A',template:'<div><span style="background-color:red;">{{mytitle}}</span><div ng-transclude></div></div>',replace:true,//将etitle属性绑定到父控制器的scope域中 scope:{ mytitle:'=etitle' },} }); app.controller('directive',function($scope){ $scope.title = "学习"; $scope.text = "angular js概念多"; });
link
link的值是一个function,一般用在在dom上绑定动作的。请看下面实现的一个折叠面板的例子。
<!DOCTYPE html> <html ng-app="directive"> <head lang="en"> <Meta charset="UTF-8"> <title>directive</title> <script src="../bower_components/angular/angular.min.js"></script> <script src="./directive.js"></script> </head> <body> <div ng-controller="directive"> <expander etitle="title">{{text}}</expander> </div> </body> </html>
var app = angular.module('directive',[]); app.directive('expander',function(){ return { restrict:'E',template:'<div><span style="background-color:red;" ng-click="toggleText()">{{mytitle}}</span><div ng-transclude ng-show="showText"></div></div>',link: function(scope,element,attr,accordionCtrl){ scope.showText = false; scope.toggleText = function(){ scope.showText = ! scope.showText; } } } }); app.controller('directive',function($scope){ $scope.title = "angular 学习"; $scope.text = "angular js概念多"; });
expander指令中的link参数中增加了showText的值和toggleText的点击函数。
最后,再看一个多个折叠面板的例子
<!DOCTYPE html> <html ng-app="directive"> <head lang="en"> <Meta charset="UTF-8"> <title>directive</title> <script src="../bower_components/angular/angular.min.js"></script> <script src="./directive.js"></script> </head> <body> <div ng-controller="directive"> <accordion> <expander ng-repeat="expander in expanders" etitle="expander.title">{{expander.text}}</expander> </accordion> </div> </body> </html>
ng-repeat便利expanders的所有元素
var app = angular.module('directive',require:'^?accordion',accordionCtrl){ scope.showText = false; accordionCtrl.addExpander(scope); scope.toggleText = function(){ scope.showText = ! scope.showText; accordionCtrl.getOpened(scope); } } } }); app.controller('directive',function($scope){ $scope.expanders = [ {title:"angular",text:"angular js概念多"},{title:"react",text:"react + reduce + ui路由机制"} ]; }); app.directive('accordion',function(){ return { restrict:"E",template:'<div ng-transclude></div>',controller:function(){ var expanders = []; this.getOpened = function(selectExpander){ angular.forEach(expanders,function(e){ if (selectExpander != e){ e.showText = false; } }); } this.addExpander = function(e){ expanders.push(e); } } } });