指令模板选项有complie和link两个字段,两者之间存在如下关系:

  • 当compile字段存在时,link字段将被忽略,compile函数的返回值将作为link字段。
  • 当compile不存在,link字段存在时,angular通过这样directive.compile
    = valueFn(directive.link);
    包装一层,使用用户定义的link字段。
而link分为preLink和postLink两个阶段,从link字段或者compile函数的返回值来看:
  • 如果是函数,那么这样的link,会被认为是postLink。
  • 如果是对象,那么link.pre作为preLink函数,link.post作为postLink函数。
app.directive('myDirective', function () {
return {
compile: function () {
return {
pre: function () {
console.log('preLink');
},
post: function () {
console.log('postLink');
}
}
}
}
});

我们的指令工厂返回的是一个函数,那么angular通过这样的包装directive
= { compile: valueFn(directive) }
,即该函数将作为指令对象的postLink函数,像这样:

app.directive('myDirective', function () {
return function () {
console.log('postLink');
}
});

angular编译链接指令的顺序

为了看清angular编译链接指令的顺序,用以下代码输出日志的方式来说明:
<body ng-app="myApp">
<A a1>
<B b1 b2></B>
<C>
<E e1></E>
<F>
<G></G>
</F>
</C>
<D d1></D>
</A>
</body> var app = angular.module('myApp', []);
var names = ['a1', 'b1', 'b2', 'e1', 'd1']; names.forEach(function (name) {
app.directive(name, function () {
return {
compile: function () {
console.log(name + ' compile');
return {
pre: function () {
console.log(name + ' preLink');
},
post: function () {
console.log(name + ' postLink');
}
};
}
};
});
});

输出:

a1 compile
b1 compile
b2 compile
e1 compile
d1 compile
a1 preLink
b1 preLink
b2 preLink
b2 postLink
b1 postLink
e1 preLink
e1 postLink
d1 preLink
d1 postLink
a1 postLink

可以看出:

  1. 所有的指令都是先compile,然后preLink,然后postLink。
  2. 节点指令的preLink是在所有子节点指令preLink,postLink之前,所以一般这里就可以通过scope给子节点传递一定的信息。
  3. 节点指令的postLink是在所有子节点指令preLink,postLink完毕之后,也就意味着,当父节点指令执行postLink时,子节点postLink已经都完成了,此时子dom树已经稳定,所以我们大部分dom操作,访问子节点都在这个阶段。
  4. 指令在link的过程,其实是一个深度优先遍历的过程,postLink的执行其实是一个回溯的过程。
  5. 节点上的可能有若干指令,在搜集的时候就会按一定顺序排列(通过byPriority排序),执行的时候,preLinks是正序执行,而postLinks则是倒序执行。

明白了这些以后,就要小心一些容易忽略的陷阱。

<body ng-app="myApp">
<my-parent></my-parent>
</body> var app = angular.module('myApp', []); app.directive('myParent', function () {
return {
restrict: 'EA',
template: '<div>{{greeting}}{{name}}'+
'<my-child></my-child>'+
'</div>',
link: function(scope,elem,attr){
scope.name = 'Lovesueee';
scope.greeting = 'Hey, I am ';
}
};
});
app.directive('myChild', function () {
return {
restrict: 'EA',
template: '<div>{{says}}</div>',
link: function(scope,elem,attr){
scope.says = 'Hey, I am child, and my parent is ' + scope.name;
}
};
});

结果子指令输出为undefined

Hey, I am Lovesueee
Hey, I am child, and my parent is undefined

由上可以,myParent指令的link是一个postLink函数,而这个函数将在myChild指令的preLink和postLink执行完之后才执行。所以scope.name = undefined。



参考链接:http://blog.csdn.net/eric_tsai/article/details/50505671




angular指令中的preLink函数和postLink函数的更多相关文章

  1. angular指令中的scope绑定策略

    针对独立 scope,可以通过在对象中声明如何从外部传入参数.有以下三种绑定策略: @ - 使用 DOM 属性值单项绑定到指令 scope 中.此时绑定的值总是一个字符串,因为 DOM 的属性值是一个 ...

  2. angular指令中@,=,&的区别

    当directive中的scope设置为一个对象的时候,该指令就有了一个独立的作用域,AngularJS提供了一种绑定策略用于隔离作用域和外部作用域进行通信. 1.@(or @attr) 使用@符号可 ...

  3. angular指令中使用ngModelController

    在这篇文章中 angular学习笔记(三十)-指令(10)-require和controller 说到了通过require属性和controller参数来让指令与指令之间互相交互. 本篇主要介绍的是指 ...

  4. angular指令中,require和transclude同时设置为true时的作用

    最近在学习angularJS指令的时候,对指令对象中require属性和transclude属性同时设置为true比较疑惑,于是自己动手测试一下具体差异 index.html: <simple& ...

  5. angularjs指令中的compile与link函数详解(转)

    http://www.jb51.net/article/58229.htm 通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link, ...

  6. 【转】angularjs指令中的compile与link函数详解

    这篇文章主要介绍了angularjs指令中的compile与link函数详解,本文同时诉大家complie,pre-link,post-link的用法与区别等内容,需要的朋友可以参考下   通常大家在 ...

  7. angularjs指令中的compile与link函数详解

    这篇文章主要介绍了angularjs指令中的compile与link函数详解,本文同时诉大家complie,pre-link,post-link的用法与区别等内容,需要的朋友可以参考下   通常大家在 ...

  8. angularjs指令中的compile与link函数详解补充

    通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link,post-link的用法与区别. angularjs里的指令非常神奇,允许你 ...

  9. [译]ng指令中的compile与link函数解析 转

    通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link,post-link的用法与区别. 原文地址 angularjs里的指令非常神 ...

随机推荐

  1. python写的一段分页的代码

    代码: from django.utils.safestring import mark_safe class Paginator(object): def __init__(self,current ...

  2. 在 JavaScript 中使用构造器函数模拟类

    今天,我们要讲的是在 JavaScript 中使用构造器函数(construcor function)模拟类. 构造器函数简介 你可以使用 ES6 的 class 关键字来实现类,不过我建议你使用传统 ...

  3. Select()使用否?

    David Treadwell ,Windows Socket 的一位开发者,曾经在他的一篇名为"Developing Transport-Independent Applications ...

  4. Linux入门之常用命令(14) kill

    Linux kill 命令使用详解 功能说明:删除执行中的程序或工作. 语 法:kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>] 补充说明: ...

  5. javascript的数值转换 number()详解

    ---恢复内容开始--- number() parseInt() parseFloat()这三个函都可以把数非数值转换为数值,我们看看他们的区别在哪里 一 Number() 转型函数Number()是 ...

  6. 在linux上安装rz、sz包

    在SecureCRT这样的ssh登录软件里, 通过在Linux界面里输入rz/sz命令来上传/下载文件. 对于RHEL5, rz/sz默认没有安装所以需要手工安装.sz: 将选定的文件发送(send) ...

  7. Python实战之IO多路复用select的详细简单练习

    IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. select   它通过一个select()系统调用来 ...

  8. 【转】 中兴OLT-C300常用命令

    中兴OLT C300show running-config (加载各种板卡)show gpon onu uncfg (查看OLT所有未配置的ONU)show gpon onu uncfg gpon-o ...

  9. Java面向对象 集合(上)

     Java面向对象  集合(上) 知识概要:             (1)体系概述 (2)共性方法 (3)迭代器 (4)list集合 (5)Set 集合 体系概述:              集 ...

  10. asp.net(C#)html无限分类树 可新增 删除 修改

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ProductSort.aspx ...