指令模板选项有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. Flask-WTF CSRF 保护P3

    使用FlaskForm处理请求的任何视图函数都已经获得了CSRF保护.如果有些视图函数还在使用FlaskForm或AJAX请求,请尽快使用FlaskForm提供的CSRF扩展来保护它们. 导入 想要为 ...

  2. JS控制台打印星星,总有你要的那一款~

    用JS语句,在控制台中打印星星,你要的是哪一款呢~来认领吧~ 1.左直角星星 效果: 代码: let readline=require("readline-sync"); cons ...

  3. 内核对象 windows操作系统

    问题: 什么是内核对象? 答:内核对象实际上时由内核分配的一块内存,而且只能由内核来访问.它时一个数据结构,成员包含有关于该对象的信息.一些成员对于所有对象类型都是一样的,比如对象名称.安全描述.使用 ...

  4. js中如何在一个函数里面执行另一个函数

    1.js中如何在函数a里面执行函数b function a(参数c){ b(); } function b(参数c){ } 方法2: <script type="text/javasc ...

  5. Valgrind检测内存泄露简介

    原文地址: Valgrind 概述 体系结构 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合.Valgrind由内核(core)以及基于内核的其他调试工具组成.内核 ...

  6. Thread.Join 和 Task.Wait 方法

    这两个方法 可以说是类似的功能,都是对当前任务进行等待阻塞,执行完毕后再进行后续处理 talk is cheap, show you code,下面一个是异步执行,一个是加了阻塞,可以对比不同执行结果 ...

  7. IDEA- idea代码调试debug

    IDEA有很多的快捷键,下面整理Debug的快捷键,方便自己使用!(阅读本篇可能花费您2分钟,需要多的实践练习) F9 resume programe 恢复程序 Alt+F10 show execut ...

  8. 51 nod 1521 一维战舰 时间复杂度O(n),同 Codeforces 567D. One-Dimensional Battle Ships 有详细注释

    题目:51nod: 题目Codeforces: 题目注意到两个战舰不能挨在一起就可以了. // 每一段 struct node{ int left; // 段的左端点 int right; // 段的 ...

  9. PHP计算上个月的开始时间和结束时间戳

    $m = date('Y-m-d', mktime(0,0,0,date('m')-1,1,date('Y'))); $t = date('t',strtotime($m)); //上个月共多少天 $ ...

  10. 悟透JavaScript(二)

    初看原型 prototype源自法语,软件界的标准翻译为“原型”,代表事物的初始形态,也含有模型和样板的意义.JavaScript中的prototype概念恰如其分地反映了这个词的内含,我们不能将其理 ...