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不得不说的故事的更多相关文章

  1. angular学习笔记(三十)-指令(7)-compile和link(2)

    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...

  2. angular指令中的preLink函数和postLink函数

    指令模板选项有complie和link两个字段,两者之间存在如下关系: 当compile字段存在时,link字段将被忽略,compile函数的返回值将作为link字段. 当compile不存在,lin ...

  3. angular指令的compile,prelink 和 postlink以及controller

    一. 指令模板选项有complie和link两个字段,两者之间存在如下关系: 当compile字段存在时,link字段将被忽略,compile函数的返回值将作为link字段. 当compile不存在, ...

  4. angular中的compile和link函数

    angular中的compile和link函数 前言 这篇文章,我们将通过一个实例来了解 Angular 的 directives (指令)是如何处理的.Angular 是如何在 HTML 中找到这些 ...

  5. angular指令深度学习篇

    angular指令深度学习-过滤器 limitTo ... <body ng-app="app" > <div ng-controller="myCtr ...

  6. Angular指令渗透式理解

    通过一段时间对angular指令的使用,理解了angular指令的意义,下面逐一介绍一下. ng-app:定义一个angualr模块,表示angular作用的范围,如下代码: ng-app在html标 ...

  7. Angular4 后台管理系统搭建(9) - 用自定义angular指令,实现在服务端验证

    最近这段时间发现,北京这用angular4 或 angular2的公司很少.几乎是没有.很担心自己是不是把精力放到了不应该的地方.白耽误了时间.但是随着我对新版angular框架理解的加深.个人感觉a ...

  8. 与《YII框架》不得不说的故事—5篇目录

    与<YII框架>不得不说的故事—基础篇 第1章 课程目标 1-1 课程目标 (00:54) 第2章 课前知识准备 2-1 YII的启动和安装 (05:12) 2-2 YII请求处理流程 ( ...

  9. 【征文】Hadoop十周年特别策划——我与Hadoop不得不说的故事

    2016年是Hadoop的十周年生日,在今年,CSDN将以技术和实战为主题与大家共同为Hadoop庆生.其主要内容包含Hadoop专业词典.系列视频技术解析.Hadoop行业实践.线上问答.线下沙龙. ...

随机推荐

  1. 手把手教你使用spring cloud+dotnet core搭建微服务架构:服务治理(-)

    背景 公司去年开始使用dotnet core开发项目.公司的总体架构采用的是微服务,那时候由于对微服务的理解并不是太深,加上各种组件的不成熟,只是把项目的各个功能通过业务层面拆分,然后通过nginx代 ...

  2. VS问题

    ref:https://q.cnblogs.com/q/86096/

  3. Server in ASP.NET-Core

    .NET-Core Series Server in ASP.NET-Core DI in ASP.NET-Core Routing in ASP.NET-Core Error Handling in ...

  4. hadoop源码import到eclipse工程

    1.解压hadoop-1.1.2.tar.gz,重点在src文件夹 2.在eclipse中通过菜单栏创建一个java工程,工程名随便 3.在创建的工程上,点击右键,在弹出菜单中选择最后一项,在弹出窗口 ...

  5. Java中的类型转换(Integer、Long、String)

    这段时间将项目中一个模块参照C++源代码,实现一个JAVA版.主要功能是将一些字段信息转换为String类型,传输后可以进行解析. Integer.Long转为String,Java本身提供了这种转换 ...

  6. M方法

    ThinkPHP函数详解:M方法 M方法用于实例化一个基础模型类,和D方法的区别在于:1.不需要自定义模型类,减少IO加载,性能较好:2.实例化后只能调用基础模型类(默认是Model类)中的方法:3. ...

  7. [Oracle]理解undo表空间

    一.回退段介绍 在Oracle数据库中,当某个事物对数据进行修改时,Oracle首先将数据的原始值保存到一个回退段中.一个事物只能将它的回退信息保存到一个回退段中,而多个并行事物可以使用同一个回退段. ...

  8. Disharmony Trees 树状数组

    Disharmony Trees Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Su ...

  9. JQ重复注册问题

    开发中常常会碰到事件重复注册,简单总结一下解决方法. (1)bind注册事件 $('...').unbind().bind('...',function(){}) (2)live注册事件 $('... ...

  10. thinkphp增删改查

    添加数据: (添加单行数据) // 添加成功返回1,失败返回0 (添加多行数据) // 返回添加数据的条数 删除数据: 修改数据: (修改单个字段) (修改多个字段) // 修改成功返回1,失败返回0 ...