前言
工作中使用angular1.x已经有很长一段时间了,但是有些angular上重要的难点,自己觉得是时候详细总结一下,一是对自己的总结,二是看自己那些还不熟悉。angular1.x
中一大难点部分就是自定义指令,接下来我尽可能详细的对angular中的directive
做总结。
下面内容都是自己一点点写上去的,如果有什么问题,请及时指正,若要转载请备注作者,谢谢配合。
如何定义一个自定义指令
1 | angular.module('app', []) |
directive中第二个参数中返回对象的配置项
大致有如下参数项:
restrict
- 作用:在DOM视图中的应用形式
- 取值:
EACM
,不是必填项 js
1
2
3
4
5
6angular.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
7angular.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
29angular.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
7angular.module('app', [])
.directive('myDirective1', function(){
return {
restrict: 'EA',
template: '<p style="color:red;">hello</p>'
}
})
templateUrl
- 作用:通过url地址把模板展示在页面上
- 取值:String(文件路径)或者Funtion
js
- 下面模板地址是在本地写的模板,一般项目中的模板都是存在后台,异步获取,这就意味着会编译或者链接,所以会用到angular中的缓存模板
$templateCache
1
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/#!/templateUrlreplace
- 作用: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: false
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: 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