前言
      工作中使用angular1.x已经有很长一段时间了,但是有些angular上重要的难点,自己觉得是时候详细总结一下,一是对自己的总结,二是看自己那些还不熟悉。angular1.x中一大难点部分就是自定义指令,接下来我尽可能详细的对angular中的directive做总结。
下面内容都是自己一点点写上去的,如果有什么问题,请及时指正,若要转载请备注作者,谢谢配合。
如何定义一个自定义指令
| 1 | angular.module('app', []) | 
directive中第二个参数中返回对象的配置项
大致有如下参数项:
restrict
- 作用:在DOM视图中的应用形式
- 取值: EACM,不是必填项
- js - 1 
 2
 3
 4
 5
 6- angular.module('app', []) 
 .directive('myDirective', function(){
 return {
 restrict: 'EACM'
 }
 })
- html - 1 
 2
 3
 4
 5
 6
 7
 8- <!-- E:(元素) --> 
 <my-directive></my-directive>
 <!-- A:(属性 默认值) -->
 <div my-directive></div>
 <!-- C:(类名) -->
 <div class="my-directive"></div>
 <!-- M:(注释) -->
 <--directive:my-directive expression-->
priority
- 作用:优先级
- 取值: Number,例如1000
- js - 1 
 2
 3
 4
 5
 6
 7- angular.module('app', []) 
 .directive('myDirective', function(){
 return {
 restrict: 'EACM',
 priority: 1000
 }
 })
terminal
- 作用:告诉angularJS是否停止运行当前元素上比本指令优先级更低的指令,但与当前指令优先级同级的指令或者更高的指令还是会被执行的
- 取值:Boolean值
- js - 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- angular.module('app', []) 
 .directive('myDirective1', function(){
 return {
 restrict: 'A',
 priority: 1,
 link: function(scope) {
 console.log('myDirective11111')
 }
 }
 })
 .directive('myDirective2', function(){
 return {
 restrict: 'A',
 priority:2,
 terminal: true,
 link: function(scope, el) {
 console.log('myDirective222222')
 }
 }
 })
 .directive('myDirective3', function(){
 return {
 restrict: 'A',
 priority:5,
 link: function(scope, el) {
 console.log('myDirective33333')
 }
 }
 })
- html - 1 
 2
 3- <div my-directive1 my-directive2 my-directive3> 
 angularJS!!!
 </div>
- result - 1.当terminal = true时,控制台会打印1 
 2myDirective222222 
 myDirective33333
 - 也就是说优先级比它低的没有执行,阻止了 - 2.当terminal = false时,控制台会打印1 
 2
 3myDirective11111 
 myDirective222222
 myDirective33333
 - 也就是说执行顺序是由低到高 - myDirective1 -> myDirective2 -> myDirective3
- 1.当
- demo
 http://zjrzpp.gitee.io/directivecase/#!/terminaltemplate
- 作用:展示在页面上的模板字符串
- 取值:String或者 Funtion
- 注意: template返回的模板中,DOM结构中必须存在一个根节点
- js - 1 
 2
 3
 4
 5
 6
 7- angular.module('app', []) 
 .directive('myDirective1', function(){
 return {
 restrict: 'EA',
 template: '<p style="color:red;">hello</p>'
 }
 })
templateUrl
- 作用:通过url地址把模板展示在页面上
- 取值:String(文件路径)或者Funtion
- js - 下面模板地址是在本地写的模板,一般项目中的模板都是存在后台,异步获取,这就意味着会编译或者链接,所以会用到angular中的缓存模板$templateCache1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12<script type="text/javascript"> 
 angular.module('app', [])
 .directive('myDirective1', function(){
 return {
 restrict: 'EA',
 templateUrl: 'template.html'
 }
 })
 </script>
 <script type="text/ng-template" id="template.html">
 <p>This is the content of the template</p>
 </script>
 
- 下面模板地址是在本地写的模板,一般项目中的模板都是存在后台,异步获取,这就意味着会编译或者链接,所以会用到angular中的缓存模板
- demo 
 http://zjrzpp.gitee.io/directivecase/#!/templateUrl- replace
- 作用:false: 模板的内容将会被插入到视图中应用指令元素的内部; true: 则表示替代,即插入到视图中时,应用指令的html元素将被删除,取而代之的是html模板。
- 取值:Boolean
- js - replace: true - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14- <script type="text/javascript"> 
 angular.module('app', [])
 .directive('myDirective1', function(){
 return {
 restrict: 'EA',
 replace: true,
 templateUrl: 'template.html',
 }
 })
 </script>
 <script type="text/ng-template" id="template.html">
 <p>This is the content of the template</p>
 </script>- result:  
- replace: false1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14<script type="text/javascript"> 
 angular.module('app', [])
 .directive('myDirective1', function(){
 return {
 restrict: 'EA',
 replace: false,
 templateUrl: 'template.html',
 }
 })
 </script>
 <script type="text/ng-template" id="template.html">
 <p>This is the content of the template</p>
 </script>
 - result:  
- demo
 http://zjrzpp.gitee.io/directivecase/#!/replace
scope
- 作用: - Boolean:默认是false,即该指令并不会创建新的作用域,改指令内部或外部的作用域是一样的; true: 会继承父作用域并创建一个新的作用域对象 - true - js - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22- <script type="text/javascript"> 
 angular.module('app', [])
 .controller('mainCtrl', ['$scope', function($scope){
 $scope.mainData = '我是main里内容'
 }])
 .directive('myDirective1', function(){
 return {
 restrict: 'EA',
 scope: true,
 templateUrl: 'submain.html',
 controller: function($scope) {
 $scope.submain = '我是指令自己的内容'
 }
 }
 })
 </script>
 <script type="text/ng-template" id="submain.html">
 <p>我能拿到父级的数据:{{mainData}}</p>
 <p>我自己的数据: {{submain}}</p>
 </script>
- html - 1 
 2
 3
 4
 5
 6- <div ng-controller="mainCtrl"> 
 父级自己的内容:{{mainData}}
 <my-directive1></my-directive1>
 </br>
 我是父级我可以访问指令里面的内容吗:{{submain}}
 </div>
- result  
- demo
 http://zjrzpp.gitee.io/directivecase/#!/scope1
 
- false - js - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22- <script type="text/javascript"> 
 angular.module('app', [])
 .controller('mainCtrl', ['$scope', function($scope){
 $scope.mainData = '我是main里内容'
 }])
 .directive('myDirective1', function(){
 return {
 restrict: 'EA',
 scope: false,
 templateUrl: 'submain.html',
 controller: function($scope) {
 $scope.submain = '我是指令自己的内容'
 }
 }
 })
 </script>
 <script type="text/ng-template" id="submain.html">
 <p>我能拿到父级的数据:{{mainData}}</p>
 <p>我自己的数据: {{submain}}</p>
 </script>
- html - 1 
 2
 3
 4
 5
 6- <div ng-controller="mainCtrl"> 
 父级自己的内容:{{mainData}}
 <my-directive1></my-directive1>
 </br>
 我是父级我可以访问指令里面的内容吗:{{submain}}
 </div>
- result  
 
 
- Object:隔离作用域,也就是隔离模板与外界作用域,但是也是可以访问外面的值,取值如下: - @ 本地作用域属性
- = 双向绑定
- & 父级作用域绑定
 
 
- 第一种使用方式 - 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- <script type="text/javascript"> 
 angular.module('app', [])
 .controller('mainCtrl', ['$scope', function($scope){
 $scope.mainData = 'parent'
 $scope.mainModel = 'aa'
 $scope.getMsg = function() {
 console.log('方法执行了')
 }
 }])
 .directive('myDirective1', function(){
 return {
 restrict: 'EA',
 scope: {
 myChild: '@', // 储存与myChild相关联的字符串
 myModel: '=', // 将myModel指定对象或者变量绑定
 myFun: '&' // 将外部方法传递给这个方法
 },
 templateUrl: 'submain.html',
 controller: function($scope) {
 }
 }
 })
 </script>
 <script type="text/ng-template" id="submain.html">
 <p>通过隔离作用域拿到父级变量值:{{myChild}}</p>
 <input type="text" ng-model="myModel">
 <button class="btn" type="button" ng-click="myFun()">提交</button>
 </script>- 1 
 2
 3
 4
 5- <div ng-controller="mainCtrl" class="main"> 
 <input type="text" ng-model="mainModel">
 <hr>
 <my-directive1 my-child="{{mainData}}" my-model="mainModel" my-fun="getMsg()"></my-directive1>
 </div>
result: 
注意:定义传参时采用的是驼峰命名法
- 第二种采用别名方式
| 1 | <script type="text/javascript"> | 
| 1 | <div ng-controller="mainCtrl" class="main"> | 
transclude
- 作用:你要不要把你指令内部的元素(不是指令的模板)嵌入到你的模板中去,
- 取值:Boolean值,默认是false; true或者Object: 它会将整个DOM嵌入到指令内部定义的模板中,包括DOM中的其他指令,经常和ng-transclude配合使用。
- transclude: true - js - 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- <script type="text/javascript"> 
 angular.module('app', [])
 .controller('demoCtrl', ['$scope', function($scope){
 $scope.datas = ['apple', 'orange', 'banana'];
 }])
 .directive('sidebox', function(){
 return {
 restrict: 'EA',
 scope: {
 title: '@',
 },
 transclude: true,
 templateUrl: 'template.html',
 }
 })
 </script>
 <script type="text/ng-template" id="template.html">
 <div class="sidebox">
 <div class="content">
 <h2 class="header">{{title}}</h2>
 <span class="content" ng-transclude></span>
 </div>
 </div>
 </script>
- html - 1 
 2
 3
 4
 5- <div title="fruit" sidebox> 
 <ul>
 <li ng-repeat="item in datas">{{item}}</li>
 </ul>
 </div>
- 图解  
- demo
 http://zjrzpp.gitee.io/directivecase/#!/transclude1
 
- transclude: Object- js
 
| 1 | <script type="text/javascript"> | 
- html - 1 
 2
 3
 4
 5
 6- <div ng-controller="demoCtrl"> 
 <main-box title="我是主指令的内容">
 <content-directive></content-directive>
 <menu-directive></menu-directive>
 </main-box>
 </div>
- 图解  
- demo
 http://zjrzpp.gitee.io/directivecase/#!/transclude2
