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下软链接与硬链接及其区别
linux下创建链接命令 ln -s 软链接 这是linux中一个非常重要命令,请大家一定要熟悉.它的功能是为某一个文件在另外一个位置建立一个不同的链接,这个命令最常用的参数是-s, 具体用法是:ln ...
- ant执行jar包中的main方法
<project name= "myproject" basedir= "." default="main"> <p ...
- linux c学习笔记----线程创建与终止
进程原语 线程原语 描述 fork pthread_create 创建新的控制流 exit pthread_exit 从现有的控制流中退出 waitpid pthread_join 从控制流中得到退出 ...
- 代码管理(四)SVN和Git对比
在日常运维工作中,经常会用到版本控制系统,目前用到最广泛的版本控制器就是SVN和Git,那么这两者之间有什么不同之处呢?SVN(Subversion)是集中式管理的版本控制器,而Git是分布式管理的版 ...
- python学习笔记——爬虫学习中的重要库urllib
1 urllib概述 1.1 urllib库中的模块类型 urllib是python内置的http请求库 其提供了如下功能: (1)error 异常处理模块 (2)parse url解析模块 (3)r ...
- 对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成
大家知道,DataSet保存的数据是位于服务器内存里面的原数据库的“副本”.所以用DataSet更新数据的过程就是先对“副本”进行更新,然后 在将“原本”更新,按照我的理解就是把“原本”覆盖掉.具体到 ...
- dbms_random.seed
语法: DBMS_RANDOM.SEED ( val IN BINARY_INTEGER); DBMS_RANDOM.SEED ( val IN VARCHAR2); val: Seed number ...
- 【转】TeXmacs:一个真正“所见即所得”的排版系统
TeXmacs:一个真正“所见即所得”的排版系统 好久没有推荐过自己喜欢的软件了,现在推荐一款我在美国做数学作业的私家法宝:TeXmacs.我恐怕不可能跟以前那么有闲心写个长篇的 TeXmacs 说明 ...
- Swift2.0语言教程之函数嵌套调用形式
Swift2.0语言教程之函数嵌套调用形式 Swift2.0语言函数嵌套调用形式 在Swift中,在函数中还能够调用函数,从而形成嵌套调用.嵌套调用的形式往往有两种:一种是在一个函数中调用其它函数:还 ...
- JAVA Socket编程和C++ Socket编程有什么不同
原文链接: http://zhidao.baidu.com/link?url=16TEzhom2Nr8x1_2uTRp-e2pgZRgS5nW5ywtRX2XLHbtLOG8btif5DTyP85jf ...