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 创建一个继承了父作用 ...
随机推荐
- 编程算法 - 迷宫的最短路径 代码(C++)
迷宫的最短路径 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定一个大小为N*M的迷宫. 迷宫由通道和墙壁组成, 每一步能够向邻接的上下 ...
- 解决inline-block上下不对齐
一开始都是行内元素,但是左边按钮和右边标题就是对不齐,于是,设置左边按钮float:left就可以了. <header class="right-header"> &l ...
- [Spring学习笔记 1 ] Spring 简介,初步知识--Ioc容器详解 基本原理。
一.Spring Ioc容器详解(1) 20131105 1.一切都是Bean Bean可是一个字符串或者是数字,一般是一些业务组件. 粒度一般比较粗. 2.Bean的名称 xml配置文件中,id属性 ...
- java 结束程序进程 代码
结束firefox的进程,一句代码就够了,如下: Runtime.getRuntime().exec("taskkill /F /IM firefox.exe"); 结束qq: R ...
- 【DeepLearning】Exercise:Softmax Regression
Exercise:Softmax Regression 习题的链接:Exercise:Softmax Regression softmaxCost.m function [cost, grad] = ...
- 自动化部署必备技能—定制化RPM包[转载]
回顾下安装软件的三种方式: 1.编译安装软件,优点是可以定制化安装目录.按需开启功能等,缺点是需要查找并实验出适合的编译参数,诸如MySQL之类的软件编译耗时过长. 2.yum安装软件,优点是全自动化 ...
- MySQL 插入emoji 表情
create table doctorUserInfoMation ( id int not null auto_increment comment '系统ID', userId ) comment ...
- 关于less在DW中高亮显示问题
首先, 找到DW 安装目录. Adobe Dreamweaver CS5.5\configuration\DocumentTypes 中的,MMDocumentTypes.xml 这个文件,然后用记事 ...
- 如何利用 Visual Studio 自定义项目或工程模板(转载)
在开发项目的时候,由其是商业性质的大型项目时,往往需要在每个代码文件上都加上一段关于版权.开发人员的信息,并且名称空间上都需要带有公司的标志.这个时候,是选择在开发的时候手动添加还是自动生成呢? 我们 ...
- easyui datagrid checkbox选中事件
$('#grid_Order').datagrid({ onCheck: function(index, data) { //alert(data[0]); / ...