angular指令之complie和link不得不说的故事
angular指令比较晦涩难懂的就是complie和link字段了,什么时候该用complie?什么时候该用link?总是很难分别清楚。当理解了指令的真正编译原理的时候,就会发现这相当的简单。
ng怎样处理指令其实是依赖于它定义时的对象属性的,你可以定义一个compile或者一个link函数,或者用pre-link和post-link函数来代替link.。
我们先看一段简单的代码:
html代码
<level-one>
<level-two>
<level-three>
Hello
</level-three>
</level-two>
</level-one>
js代码
var app = angular.module('plunker', []);
function createDirective(name){
return function(){
return {
restrict: 'E',
compile: function(tElem, tAttrs){
console.log(name + ': compile => ' + tElem.html());
return {
pre: function(scope, iElem, iAttrs){
console.log(name + ': pre link => ' + iElem.html());
},
post: function(scope, iElem, iAttrs){
console.log(name + ': post link => ' + iElem.html());
}
}
}
}
}
}
app.directive('levelOne', createDirective('levelOne'));
app.directive('levelTwo', createDirective('levelTwo'));
app.directive('levelThree', createDirective('levelThree'));
结果:
关于complie和preLink和postLink的调用顺序可以参考我的上一篇博文。
在这里再简要说明一下,从上面的结果可以看出,所有的指令都是先compile,然后preLink,然后postLink。节点指令的preLink是在所有子节点指令preLink,postLink之前,所以一般这里就可以通过scope给子节点传递一定的信息。节点指令的postLink是在所有子节点指令preLink,postLink完毕之后,也就意味着,当父节点指令执行postLink时,子节点postLink已经都完成了,此时子dom树已经稳定,所以我们大部分dom操作,访问子节点都在这个阶段。
这里我们主要来看一下complie、preLink和postLink函数中element属性有什么不同?scope作用域又是什么时候绑定的?
如果你仔细观察的话,就会发现上述结果中,传递给complie的element参数是最原始的html标志,变量指向的是template element。一旦运行levelone指令中的compile函数,ng就会递归深度遍历它的dom节点,然后在level-two与level-three上面重复这些操作.。因为complie的element是原始的html,所以可以在ng创建element实例以及创建scope对象之前改变dom的结构,以便在只有一个template element的情况下,生成多个element实例,例如ngRepeat。
因为在complie阶段,element还是原生的html,所以此时的scope是还没有创建的,complie函数不能够访问scope。在complie完成之后,将创建template element的element实例以及实例的scope。当linking发生时,这个实例element以及scope对象已经是可用的了,并被传递给preLink函数。所以preLink中的element不是一个原始的html,而是一个element实例,它拥有一个scope。同样的情况也在postLink之中。
一个元素的pre-link函数能够保证是运行在它所有的子指令的post-link与pre-link运行之前执行的。正如之前所说的一般这里就可以通过scope给子节点传递一定的信息。当运行包含子指令的指令post-link时,反向的post-link规则可以保证它的子指令的post-link是已经运行过的,这就是为什么人们都认为post-link是最安全或者默认的写业务逻辑的地方.。
参考链接:http://www.jb51.net/article/58229.htm
angular指令之complie和link不得不说的故事的更多相关文章
- angular学习笔记(三十)-指令(7)-compile和link(2)
继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...
- angular指令中的preLink函数和postLink函数
指令模板选项有complie和link两个字段,两者之间存在如下关系: 当compile字段存在时,link字段将被忽略,compile函数的返回值将作为link字段. 当compile不存在,lin ...
- angular指令的compile,prelink 和 postlink以及controller
一. 指令模板选项有complie和link两个字段,两者之间存在如下关系: 当compile字段存在时,link字段将被忽略,compile函数的返回值将作为link字段. 当compile不存在, ...
- angular中的compile和link函数
angular中的compile和link函数 前言 这篇文章,我们将通过一个实例来了解 Angular 的 directives (指令)是如何处理的.Angular 是如何在 HTML 中找到这些 ...
- angular指令深度学习篇
angular指令深度学习-过滤器 limitTo ... <body ng-app="app" > <div ng-controller="myCtr ...
- Angular指令渗透式理解
通过一段时间对angular指令的使用,理解了angular指令的意义,下面逐一介绍一下. ng-app:定义一个angualr模块,表示angular作用的范围,如下代码: ng-app在html标 ...
- Angular4 后台管理系统搭建(9) - 用自定义angular指令,实现在服务端验证
最近这段时间发现,北京这用angular4 或 angular2的公司很少.几乎是没有.很担心自己是不是把精力放到了不应该的地方.白耽误了时间.但是随着我对新版angular框架理解的加深.个人感觉a ...
- 与《YII框架》不得不说的故事—5篇目录
与<YII框架>不得不说的故事—基础篇 第1章 课程目标 1-1 课程目标 (00:54) 第2章 课前知识准备 2-1 YII的启动和安装 (05:12) 2-2 YII请求处理流程 ( ...
- 【征文】Hadoop十周年特别策划——我与Hadoop不得不说的故事
2016年是Hadoop的十周年生日,在今年,CSDN将以技术和实战为主题与大家共同为Hadoop庆生.其主要内容包含Hadoop专业词典.系列视频技术解析.Hadoop行业实践.线上问答.线下沙龙. ...
随机推荐
- mongodb 3.4 集群搭建升级版 五台集群
最新版mongodb推荐使用yaml语法来做配置,另外一些旧的配置在最新版本中已经不在生效,所以我们在生产实际搭建mongodb集群的时候做了一些改进.如果大家不熟悉什么是分片.副本集.仲裁者的话请先 ...
- 验证整数 Double 转 int 两种写法
Double 转int 1)之前一直是使用强转 Double num = Double.parseDouble(object.toString()); int n = (int)num; i ...
- RabbitMQ消息队列之二:消费者和生产者
在使用RabbitMQ之前,需要了解RabbitMQ的工作原理. RabbitMQ的工作原理 RabbitMQ是消息代理.从本质上说,它接受来自生产者的信息,并将它们传递给消费者.在两者之间,它可以根 ...
- jquery自定义banner图滚动插件---(解决最后一张图片倒回第一张图片的bug)
banner图的滚动效果动画 最近做项目中banner滚动的时候遇到了一个小bug,当banner滚动到最后一张图再跳回第一张图时, 会出现默认的倒回第一张图的过渡效果,看了几个插件都是这样,所以自定 ...
- codeigniter 去除index.php (nginx,apache) 通用方法
.htaccess文件配置 1 <IfModule mod_rewrite.c> 2 RewriteEngine On 3 RewriteBase / 4 RewriteCond $1 ! ...
- Thread.Join 和 Task.Wait 方法
这两个方法 可以说是类似的功能,都是对当前任务进行等待阻塞,执行完毕后再进行后续处理 talk is cheap, show you code,下面一个是异步执行,一个是加了阻塞,可以对比不同执行结果 ...
- Qt实现基本QMainWindow主窗口程序
这个实验用Qt实现基本QMainWindow主窗口 先上实验效果图 打开一个文件,读取文件类容 详细步骤: 1.打开Qt creator新建MainWindow工程 右键工程名添加新文件,mai ...
- Eclipse连接SQL Server 2008数据库 以及问题总结
Eclipse中使用SQL server 2008数据库 一.准备材料 要能够使用数据库就要有相应的JDBC,所以我们要去Microsoft官网下载 https://www.microsoft.com ...
- POJ 3923 Ugly Windows(——考察思维缜密性的模拟题)
题目链接: http://poj.org/problem?id=3923 题意描述: 输入一个n*m的屏幕 该屏幕内有至少一个对话框(每个对话框都有对应的字母表示) 判断并输出该屏幕内处于最表层的对话 ...
- uvalive 3029 City Game
https://vjudge.net/problem/UVALive-3029 题意: 给出一个只含有F和R字母的矩阵,求出全部为F的面积最大的矩阵并且输出它的面积乘以3. 思路: 求面积最大的子矩阵 ...