angular学习笔记(三十)-指令(7)-compile和link(2)
继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1)
上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序.
看一段三个指令嵌套的代码:
html:
<body>
<div ng-controller="compileCtrl">
<level-one>
<level-two>
<level-three>
hello,{{name}}
</level-three>
</level-two>
</level-one>
</div>
</body>
js:
/*20.8.2 指令-compile和link*/
var appModule = angular.module('dirAppModule',[]);
appModule.controller('compileCtrl',function($scope){
$scope.name="code_bunny"
});
appModule.directive('levelOne',function(){
return {
restrict:'E',
compile:function(tEle,tAttrs,trans){
console.log('compile→'+'levelOne');
return {
pre:function(){
console.log('pre→'+'levelOne')
},
post:function(){
console.log('post→'+'levelOne')
}
}
}
}
});
appModule.directive('levelTwo',function(){
return {
restrict:'E',
compile:function(tEle,tAttrs,trans){
console.log('compile→'+'levelTwo');
return {
pre:function(){
console.log('pre→'+'levelTwo')
},
post:function(){
console.log('post→'+'levelTwo')
}
}
}
}
});
appModule.directive('levelThree',function(){
return {
restrict:'E',
compile:function(tEle,tAttrs,trans){
console.log('compile→'+'levelThree');
return {
pre:function(){
console.log('pre→'+'levelThree')
},
post:function(){
console.log('post→'+'levelThree')
}
}
}
}
});
得到结果:
因此,他们的执行顺序如下:
1.从外层到内层执行指令的compile函数
2.compile执行完毕以后,从外层到内层执行指令的pre-link函数
3.pre-link全部执行完以后,从内层到外层执行指令的post-link函数
代码测试地址:http://jsfiddle.net/9hoqvtja/1/
然后我们修改一下js代码如下:
/*20.8.2 指令-compile和link*/
appModule.directive('levelOne',function(){
return {
restrict:'E',
scope:true,
compile:function(tEle,tAttrs,trans){
console.log('compile→'+'levelOne'+tEle.html());
return {
pre:function(scope,iEle,iAttrs){
console.log('pre→'+'levelOne'+iEle.html())
},
post:function(scope,iEle,iAttrs){
console.log('post→'+'levelOne'+iEle.html())
}
}
}
}
});
appModule.directive('levelTwo',function(){
return {
restrict:'E',
scope:true,
compile:function(tEle,tAttrs,trans){
console.log('compile→'+'levelTwo'+tEle.html());
return {
pre:function(scope,iEle,iAttrs){
console.log('pre→'+'levelTwo'+iEle.html())
},
post:function(scope,iEle,iAttrs){
console.log('post→'+'levelTwo'+iEle.html())
}
}
}
}
});
appModule.directive('levelThree',function(){
return {
restrict:'E',
scope:true,
compile:function(tEle,tAttrs,trans){
console.log('compile→'+'levelThree'+tEle.html());
return {
pre:function(scope,iEle,iAttrs){
console.log('pre→'+'levelThree'+iEle.html())
},
post:function(scope,iEle,iAttrs){
console.log('post→'+'levelThree'+iEle.html())
}
}
}
}
});
我们给指令添加scope属性,在打印的过程中加入打印tEle和iEle的内容,结果如下:
可以看到,才compile阶段打印出的元素,是没有class属性的,但是在pre-link和post-link阶段打印出的元素,class属性为ng-scope ng-binding.
原因是:
compile阶段得到的元素是tElement,也就是templateElement,是原始的元素.
link阶段(无论是pre-link还是post-link),得到的是元素是iElement,也就是instanceElement,是经过compile编译后的元素的实例.
那么原始的元素和元素的实例有什么区别呢? 我的理解(不一定对)是:tElement就是最原始的元素,也就会说,页面里写的html是啥,它就是啥.而iElement就经过了angular的编译处理了.他具体处理了一些什么事情,我现在不知道,但是就这个例子,可以看到,它至少处理了'给元素绑定scope作用域','对元素里的数据与模型进行双向绑定',当然他一定还处理了很多其他的事情...这就是为什么compile是没有scope参数的,因为它还没有编译嘛~
代码测试地址:http://jsfiddle.net/0kgn110u/1/
总结一下刚才讲的所有知识:
1.compile函数的执行顺序是从父元素向子元素执行.当某个指令的compile被执行时,它的父元素的compile都已经被执行了.它的tEle参数和tAttrs参数,指的的原始的元素和原始元素的属性,原始元素没有经过angular编译.
2.pre-link函数的执行顺序是从父元素向子元素执行.当某个指令的pre-link被执行时,它的父元素和它自己的compile函数,以及它的父元素的pre-link函数都已经被执行了.它的iEle参数和iAttrs参数,指的是经过ng编译的元素.
3.post-link函数的执行顺序是从子元素向父元素执行.当某个指令的post-link被执行时,它的父元素和它自己的compile函数,以及它的子元素的post-link函数都已经被执行了.它的iEle函数和iAttrs参数,指的是,经过ng编译的元素.
参考文献:[译]ng指令中的compile与link函数解析
但是上面说的这一切,当指令中有template(templateUrl)的时候,它compile和link的执行顺序就不是这样的了.下一篇继续讲解这种情况.
angular学习笔记(三十)-指令(7)-compile和link(2)的更多相关文章
- angular学习笔记(三十)-指令(7)-compile和link(1)
这篇主要讲解指令中的compile,以及它和link的微妙的关系. link函数在之前已经讲过了,而compile函数,它和link函数是不能共存的,如果定义了compile属性又定义link属性,那 ...
- angular学习笔记(三十)-指令(7)-compile和link(3)
本篇接着上一篇来讲解当指令中带有template(templateUrl)时,compile和link的执行顺序: 把上一个例子的代码再进行一些修改: 1.将level-two指令改成具有templa ...
- angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令
在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...
- angular学习笔记(三十)-指令(10)-require和controller
本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...
- angular学习笔记(三十)-指令(5)-link
这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...
- angular学习笔记(三十)-指令(2)-restrice,replace,template
本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...
- angular学习笔记(三十)-指令(1)-概述
之前在 angular学习笔记(十九)-指令修改dom 里面已经简单的提到了angular中的指令,现在来详细的介绍 '指令' 一.指令的创建: dirAppModule.directive('dir ...
- angular学习笔记(三十)-指令(4)-transclude
本篇主要介绍指令的transclude属性: transclude的值有三个: 1.transclude:false(默认值) 不启用transclude功能. 2.transclude:true 启 ...
- angular学习笔记(三十)-指令(8)-scope
本篇讲解指令的scope属性: scope属性值可以有三种: 一.scope:false 默认值,这种情况下,指令的作用域就是指令元素当前所在的作用域. 二.scope:true 创建一个继承了父作用 ...
随机推荐
- Linux下ls与cp命令
Linux熟练的应用命令,才可以随心所欲~ ls 注意: ls -1 //每次只列出1个文件 cp 注意: cp -u xxx xxx //注意修改时间的先后
- 《数字图像处理原理与实践(MATLAB版)》一书之代码Part5
<数字图像处理原理与实践(MATLAB版)>一书之代码Part5 本文系<数字图像处理原理与实践(MATLAB版)>一书之代码系列的Part5.辑录该书第225至第280页之代 ...
- spring事务配置的两种方式
spring所有的事务管理策略类都继承自org.springframework.transaction.PlatformTransactionManager接口. <!-- 事务管理器配置,单数 ...
- Python函数的静态变量
C语言中,在函数内部可以定义static类型的变量,这个变量是属于这个函数的全局对象.在Python中也可以实现这样的机制. def f(): if not hasattr(f, 'x'): f.x ...
- 【经验总结】 fisheye 3.1.5 安装、破解全过程 图文教程(2.0以上版本均可成功!)
声明:此破解仅为个人娱乐,如果你有钱,请支持正版! 重要说明,只要把fisheye先关掉即可,然后执行下面的破解步骤,一样可以破解!本人已测试通过. 一.安装.破解fisheye最新版3.1.5 所需 ...
- iOS 性能调优
1.内存空间的划分: 我们知道,一个进程占用的内存空间,包含5种不同的数据区:(1)BSS段:通常是存放未初始化的全局变量:(2)数据段:通常是存放已初始化的全局变量.(3)代码段:通常是存放程序执行 ...
- Linux主要shell命令详解(下)
命令行编辑操作 功能 Ctrl+b或左箭头键 左移一个字符(移至前一个字符) Ctrl+f或右箭头键 右移一个字符(移至后一个字符) Ctrl+a 移至行首 Ctrl+e 移至行尾 Esc b 左移一 ...
- MySQL安装Altas
准备工作:需要先把MySQL主从配置好. 0.下载altas:打开https://github.com/Qihoo360/Atlas/releases wget https://github.com/ ...
- 在Linux下安装RabbitMQ
Installing on RPM-based Linux (CentOS, Fedora, OpenSuse, RedHat) 安装新版本的RabbitMQ出错: centos端口转发神器:soca ...
- ==和equals的简单比较
前言:==和equals这个两个东西,经常放在一块做比较,下面我也给出一个简单的例子,对他俩进行一个简单的比较,先看例子,然后在看结论.(实验环境:win7+jdk7) 1:==和equals简单比较 ...