指令是所有AngularJS应用最重要的部分。尽管AngularJS已经提供了非常丰富的指令,但还是经常需要创建应用特定的指令。这篇文章会为你讲述如何自定义指令,创建装饰型指令以及组件式指令来扩展html标签.深入指令的所有用法,彻底领会angular指令的魅力。

1.angular中的指令
1.1 创建指令
| 1 2 3 4 5 6
 | var app = angular.module('appModule',[]); app.directive('myDire',function () {     return {              } });
 | 
1.2 模板
| 1 2 3 4 5 6
 | var app = angular.module('appModule',[]); app.directive('myDire',function () {     return { +       template:'<div>Hello</div>'        } });
 | 
1.3 transclude
保留指令中的内容
| 1
 | <my-dire>world</my-dire>
 | 
| 1 2 3 4 5
 | return { +    transclude:true, -    template:'<div>Hello</div>' +    template:'<div>Hello <span ng-transclude></span></div>' }
 | 
1.3.1 面板
引入bootstrap
| 1
 | <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.css">
 | 
增加panel.html
| 1 2 3 4 5
 | <div class="panel panel-default">   <div class="panel-heading">这是一个面板</div>   <div class="panel-body" ng-transclude>   </div> </div>
 | 
修改指令代码
| 1 2 3 4
 | return {     transclude:true, +   templateUrl:'panel.html', }
 | 
1.4 link函数
link函数是用来链接视图和scope  
- scope:当前作用域
- element:jq对象
- attrs:当前指令上的属性  
| 1 2 3 4 5 6 7
 | return {        transclude:true,        templateUrl:'panel.html', +      link: function (scope,element,attrs) { +                       +      } }
 | 
1.4.1 给面板增加传入的标题
增加title属性
| 1
 | <my-dire title="这是头部">这是一个面板,helloAngular</my-dire>
 | 
增加属性值
| 1 2 3 4
 | <div class="panel panel-default"> +    <div class="panel-heading">{{title}}</div>      <div class="panel-body" ng-transclude></div> </div>
 | 
声明标题
| 1 2 3 4 5
 | return{     link: function (scope,element,attrs) { +      scope.title = attrs["title"];     } }
 | 
1.5 独立作用域
可以为当前指令设置独立作用域
| 1 2 3
 | return { +  scope:true, }
 | 
1.6 动态引用数据
1.6.1 “@”引用字符串
指令和作用域间的交互
声明控制器
| 1 2 3 4 5 6
 | app.controller('appCtrl',function ($scope) {     $scope.title = [         {name:'第一个面板'},         {name:'第二个面板'}     ] });
 | 
挂载scope上的属性
| 1 2
 | <my-dire title="{{title[0].name}}">这是一个面板,helloAngular</my-dire> <my-dire title="{{title[1].name}}">这是二个面板,helloAngular</my-dire>
 | 
在当前作用域下声明title属性,引用对应的值
| 1 2 3 4 5 6 7
 | return {     transclude:true,     templateUrl:'panel.html',     scope:{         title:'@'     } }
 | 
1.6.2 “=”引用scope上的属性
修改html
| 1 2
 | <my-dire title="title1">这是一个面板,helloAngular</my-dire> <my-dire title="title2">这是一个面板,helloAngular</my-dire>
 | 
增加动态属性
| 1 2 3 4
 | app.controller('appCtrl',function ($scope) {     $scope.title1 = 'hello1';     $scope.title2 = 'hello2' });
 | 
修改指令
1.6.3 “=”与”@”区别
@单向绑定
html页面
| 1 2
 | 控制器:<input type="text" ng-model="home"> <my-dire home="{{home}}"></my-dire>
 | 
控制器
| 1 2 3 4 5 6 7 8 9 10 11 12
 | app.controller('appCtrl',function ($scope) {     $scope.home = 'home' }); app.directive('myDire',function () {     return {         transclude:true,         template:'指令内部<input type="text" ng-model="home">',         scope:{             home:'@'         }     } });
 | 
=双向绑定
html页面
| 1
 | 控制器:<input type="text" ng-model="hobby">
 | 
| 1 2 3 4 5 6 7 8 9 10 11
 | app.controller('appCtrl',function ($scope) {      $scope.home = 'home'; +    $scope.hobby = 'hobby'; }); return { +   template:'指令内部<input type="text" ng-model="hobby">',     scope:{          home:'@', +        hobby:'='     } }
 | 
1.6.4 &绑定函数
html绑定方法
| 1
 | <my-dire home ="home(person)" name="{{name}}"></my-dire>
 | 
指令中调用函数
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14
 | app.controller('appCtrl',function ($scope) {     $scope.name = 'zfpx';     $scope.home = function (who) {         alert(who);     } }); app.directive('myDire',function () {     return {         template:'{{name}}<div ng-click="home({person:name})">谁的家</div>',         scope:{             home:'&',name:'@'         }     } });
 | 
1.7 replace替换指令
增加replace:true替换原有指令
| 1 2 3
 | return {     replace:true }
 | 
1.8 compile函数
在link函数前执行,编译模板,返回的函数为link函数
| 1
 | <my-dire time="3"></my-dire>
 | 
指令中增加compile函数
| 1 2 3 4 5 6 7 8 9 10 11 12 13
 | return {     transclude:true,     template:'<div>Hello,zfpx {{title}}</div>',     compile: function (element,attrs) {         var tmpl = element.children();         for(var i = 0; i < attrs.time-1;i++){             element.append(tmpl.clone());         }         return function (scope,element,attrs) {             scope.title = '123';         }     }, }
 | 
2.指令和指令间的交互
创建多个指令,依赖于girl指令
| 1
 | <girl love-money  ng-click="show()">Angular MM</girl>
 | 
创建指令公有部分
| 1 2 3 4 5 6 7 8 9 10 11 12 13
 | app.directive('girl',function () {     return {         controller: function ($scope) {             var arr = [];             this.add = function (attrs) {                 arr.push(attrs);             };             $scope.show = function () {                 alert(arr);             }         }     } });
 | 
创建指令间的依赖
| 1 2 3 4 5 6 7 8
 | app.directive('loveMoney',function () {     return {         require:'^girl',         link: function (scope,element,attrs,girlCtrl) {             girlCtrl.add('loveMoney');         }     } });
 | 
3.opener指令demo
增加css样式
| 1 2 3 4 5 6 7 8 9 10 11
 | .title{     width: 100px;     height: 30px;     line-height: 30px;     background: yellow; } .content{     width: 100px;     height: 100px;     background: red; }
 | 
增加指令
| 1
 | <opener title="标题1">这是内容1</opener>
 | 
增加引用模板
| 1 2
 | <div class="title" ng-click="show()">{{title}}</div> <div class="content" ng-show="flag" ng-transclude></div>
 | 
增加指令
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
 | app.directive('opener',function () {     return {         templateUrl:'open.html',         transclude:true,         scope:{             title:'@'         },         link:function(scope,element,attrs){             scope.flag = true;             scope.show = function () {                 scope.flag = !scope.flag;             }         }     } });
 | 
4.opener组
增加组
| 1 2 3 4
 | <group>     <opener title="标题1">这是内容1</opener>     <opener title="标题2">这是内容2</opener> </group>
 | 
设置指令
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
 | app.directive('group', function () {     return {         controller: function ($scope) {             var arr = [];             this.add = function (scope) {                 arr.push(scope);             }             this.close = function (scope) {                 for(var i = 0; i<arr.length;i++){                     if(arr[i]!=scope){                         arr[i].flag = false;                     }                 }             }         }     } }); app.directive('opener',function () {     return {         templateUrl:'open.html',         transclude:true,         require:'^group',         scope:{             title:'@'         },         link:function(scope,element,attrs,groupCtrl){             scope.flag = false;             scope.show = function () {                 scope.flag = !scope.flag;                 groupCtrl.close(scope);             };             groupCtrl.add(scope);         }     } });
 |