angular.js最为强大的地方在于可以通过自定义指令来扩展html元素,这种思路与JSP的taglib类似,但在实现细节上更为自由,并且自定义指令也可以提供表单元素交互、数据绑定、事件处理功能。
创建自定义指令的基本格式为:
angular.module('myApp',[]).directive('myDirective',function(){ return { restrict :'EA', scope:true, template:``//ES6多行字符支持,模板文本字符串,也可使用templateUrl replace:true, transclude:true, link:function(){ //DOM operates. } } })
1.指令行为限制
A:用于限制属性,例如<div my-exp='something'></div>
E:用于限制元素,即可直接使用该指令作为html标签使用
C:用作html元素的class类。
2.指令作用域
最简单的做法是在创建自定义指令时将scope属性设置为 true从而共享父作用域,缺点是无法避免指令中修改父作用域的值。因此,通常的做法是为指令添加隔离作用域。在隔离作用域中,以下三个运算符的使用较为重要:
@:取DOM节点的属性值到隔离作用域中使用,
=:将$scope中的属性值与隔离作用域中的值进行双向绑定,
&:将$scope中的函数绑定到隔离作用域中(仅适用于函数)。
扫描二维码关注公众号,回复:
500312 查看本文章
3.链接函数
自定义指令中可通过link函数修改DOM,通常被设置为一个postLink函数,实际上还可以设置一个preLink函数用于在元素链接之前执行。
以下示例提供了较为复杂的自定义指令,包含上述所有语法要点:
<!DOCTYPE HTML> <html ng-app='myApp'> <head> <meta charset='utf-8'> <title>Event key</title> <style type="text/css"> .expander { border: 1px solid black; width: 250px; } .expander>.title { background-color: black; color: white; padding: .1em .3em; cursor: pointer; } .expander>.body { padding: .1em .3em; } </style> </head> <body> <div ng-controller='SomeController'> <expander class='expander' title='title' click-fnc='clickFnc()'> {{text}} </expander> </div> </body> <script src='http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js'></script> <script> var app = angular.module('myApp',[]); app.controller('SomeController',function($scope){ $scope.title = 'Click to expand'; $scope.text = 'Some content inside this expander'; $scope.clickFnc = function(){ console.log("I'm clicked."); } }) .directive('expander',function(){ return { restrict:'EA', replace:true, transclude:true, scope: { title: '=title', clickFnc: '&clickFnc' }, template:`<div> <div class='title' ng-click='toggle();clickFnc()'>{{title}}</div> <div class='body' ng-show='showMe' ng-transclude></div> </div>`, link:{ pre:function preLink(scope,element,attrs){ console.log("Pre link"); }, post:function postLink(scope,element,attrs){ console.log("Post link."); scope.showMe = false; scope.toggle = function toggle(){ scope.showMe = !scope.showMe; } } } } }); </script> </body> </html>