I've talked about the timing of directives in AngularJS a few times before. But, it's a rather complicated topic, so I don't mind digging a bit deeper. This time, I'm looking at the timing of directive controllers vs. directive link functions. As the DOM (Document Object Model) is compiled by AngularJS, the directive controllers and link functions execute at different parts of the compile lifecycle.

When AngularJS compiles the DOM, it walks the DOM tree in a depth-first, top-down manner. As it walks down the DOM, it instantiates the directive controllers. Then, when it gets to the bottom of a local DOM tree branch, it starts linking the directives in a bottom-up manner as it walks back up the branch. This doesn't mean that all directive controllers are run before all directive linking; it simply means that in a local DOM branch, the directive controllers are instantiated before they are linked.

To see this in action, I've put together a very simple DOM tree in which each element has a unique (but almost identical) directive. As each directive controller and link function is executed, it will log to the console. This way, we can see the timing of the various methods in relation to the DOM tree structure.

<!doctype html>
<html ng-app="Demo">
<head>
<meta charset="utf-8" /> <title>
Directive Controller And Link Timing In AngularJS
</title>
</head>
<body> <h1>
Directive Controller And Link Timing In AngularJS
</h1> <div bn-outer> <p bn-mid> <span bn-inner> Woot! </span> </p> <p bn-second-mid> Woot, indeed! </p> </div> <!-- Load scripts. -->
<script type="text/javascript" src="../../vendor/jquery/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="../../vendor/angularjs/angular-1.2.4.min.js"></script>
<script type="text/javascript">
// Create an application module for our demo.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// I demonstrate the timing of directive execution.
app.directive(
"bnOuter",
function() {
function Controller( $scope ) {
console.log( "Outer - Controller" );
}
function link( $scope, element, attributes, controller ) {
console.log( "Outer - Link" );
}
// Return directive configuration.
return({
controller: Controller,
link: link
});
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I demonstrate the timing of directive execution.
app.directive(
"bnMid",
function() {
function Controller( $scope ) {
console.log( "Mid - Controller" );
}
function link( $scope, element, attributes, controller ) {
console.log( "Mid - Link" );
}
// Return directive configuration.
return({
controller: Controller,
link: link
});
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I demonstrate the timing of directive execution.
app.directive(
"bnSecondMid",
function() {
function Controller( $scope ) {
console.log( "Second Mid - Controller" );
}
function link( $scope, element, attributes, controller ) {
console.log( "Second Mid - Link" );
}
// Return directive configuration.
return({
controller: Controller,
link: link
});
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I demonstrate the timing of directive execution.
app.directive(
"bnInner",
function() {
function Controller( $scope ) {
console.log( "Inner - Controller" );
}
function link( $scope, element, attributes, controller ) {
console.log( "Inner - Link" );
}
// Return directive configuration.
return({
controller: Controller,
link: link
});
}
);
</script> </body>
</html>

  

Before we look at the console output, take note that there are two "mid" branches. This means that AngularJS has two branches to explore before it can fully walk back up to the top DOM node. That said, when we do run the above code, we get the following console log output:

Outer - Controller
Mid - Controller
Inner - Controller
Inner - Link
Mid - Link
Second Mid - Controller
Second Mid - Link
Outer - Link

As you can see, as AngularJS walks the DOM tree, it instantiates the directive controllers on the way down; then, it links the directives on the way back up.

This is an important difference. While you can only access the DOM tree in the bottom-up linking phase, the directive controller can provide a hook into the top-down lifecycle. This can be critical if you have to handle DOM events based on when elements of the DOM tree came into existence. The linking phase can never give you that because it's executed in reverse.

Directive Controller And Link Timing In AngularJS的更多相关文章

  1. angularJS directive中的controller和link function辨析

    在angularJS中,你有一系列的view,负责将数据渲染给用户:你有一些controller,负责管理$scope(view model)并且暴露相关behavior(通过$scope定义)给到v ...

  2. 【转载】AngularJs 指令directive之controller,link,compile

    关于自定义指令的命名,你可以随便怎么起名字都行,官方是推荐用[命名空间-指令名称]这样的方式,像ng-controller.不过你可千万不要用 ng-前缀了,防止与系统自带的指令重名.另外一个需知道的 ...

  3. 49.AngularJs 指令directive之controller,link,compile

    转自:https://www.cnblogs.com/best/tag/Angular/ 关于自定义指令的命名,你可以随便怎么起名字都行,官方是推荐用[命名空间-指令名称]这样的方式,像ng-cont ...

  4. AngularJS之指令中controller与link(十二)

    前言 在指令中存在controller和link属性,对这二者心生有点疑问,于是找了资料学习下. 话题 首先我们来看看代码再来分析分析. 第一次尝试 页面: <custom-directive& ...

  5. AngularJS的指令(Directive) compile和link的区别及使用示例

    如果我想实现这样一个功能,当一个input失去光标焦点时(blur),执行一些语句,比如当输入用户名后,向后台发ajax请求查询用户名是否已经存在,好有及时的页面相应. 输入 camnpr 失去焦点后 ...

  6. Angularjs Directive - Compile vs. Link

    如果我想实现这样一个功能,当一个input失去光标焦点时(blur),执行一些语句,比如当输入用户名后,向后台发ajax请求查询用户名是否已经存在,好有及时的页面相应. 输入 hellobug  失去 ...

  7. anagularJs指令的controller,link,compile有什么不同

    /directives.js增加exampleDirective phonecatDirectives.directive('exampleDirective', function() { retur ...

  8. controller,link,compile不同

    测试案例 .directive('testDirective', function() { return { restrict: 'E', template: '<p>Hello {{nu ...

  9. angularjs1.x的directive中的link参数element见解

    angular.module("APP",[]) .directive("testDw",function () { return{ restrict:&quo ...

随机推荐

  1. 利用git把本地项目传到github+将github中已有项目从本地上传更新

    利用git把本地项目传到github中 1.打开git bash命令行,进入到要上传的项目中,比如Spring项目,在此目录下执行git init 的命令,会发下在当前目录中多了一个.git的文件夹( ...

  2. go语言中的json

    结构体类型转化为json格式 package main import ( "encoding/json" "fmt" ) //如果要转化成json格式,那么成员 ...

  3. javascript中判断变量时变量值为 0 的特殊情况

    有时候我们在js中会直接判断变量是否存在值,下面列举一些情况: var a = 0; var b = 1; var c = ' '; var d; console.log( a ? 1 : null) ...

  4. C#字节数组的常用解码处理方法

    在某些情况下,比如说串口通信或者读取二进制的文件,通常会得到一个byte数组形式的数据. 然而对于这个数据处理常常令人苦恼,因为通常通信情况下,并不是一个字节代表一个字符或者某个数据,而是数据夹杂在字 ...

  5. jquery请求格式和返回类型 汇总

    常规请求基本格式 1 [WebMethod] 2 public string SayHello(string name) 3 { 4 return "Hello " + name; ...

  6. java使用maven项目(二)分模块开发

    1       整合ssh框架 1.1     依赖传递 只添加了一个struts2-core依赖,发现项目中出现了很多jar, 这种情况 叫 依赖传递 1.2     依赖版本冲突的解决 1.  第 ...

  7. 转载---sql之left join、right join、inner join的区别

    原文地址:http://www.cnblogs.com/pcjim/articles/799302.html sql之left join.right join.inner join的区别 left j ...

  8. [BZOJ1491][NOI2007]社交网络 floyd

    1491: [NOI2007]社交网络 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2196  Solved: 1170[Submit][Status ...

  9. Ubuntu 16.04 win7 双系统时间问题

    在安装了win7的电脑上又装了一个Ubuntu 16.04,这Ubuntu的启动速度慢就选不说了,切加win7之后发现时间也不对啊. 所以记一个随笔记录一下自己修改双系统的日期. 当然,网上也搜过,说 ...

  10. 使用base64对图片的二进制进行编码,使其可以利用ajax进行显示

    有时候我们需要动态的将图片的二进制在页面上进行显示,如我们需要弄一个验证码的功能,那么如果我们的验证码的图片在后台得到的是该图片的二进制,那么当我们需要在页面上点击一个按钮利用ajax进行切换的时候, ...