angular指令之complie和link不得不说的故事

angular指令比较晦涩难懂的就是complie和link字段了,何时该用complie?何时该用link?老是很难分别清楚。当理解了指令的真正编译原理的时候,就会发现这至关的简单。javascript

ng怎样处理指令实际上是依赖于它定义时的对象属性的,你能够定义一个compile或者一个link函数,或者用pre-link和post-link函数来代替link.。
css

咱们先看一段简单的代码:html

html代码java

<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操做,访问子节点都在这个阶段。markdown


这里咱们主要来看一下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。app


由于在complie阶段,element仍是原生的html,因此此时的scope是尚未建立的,complie函数不可以访问scope。在complie完成以后,将建立template element的element实例以及实例的scope。当linking发生时,这个实例element以及scope对象已是可用的了,并被传递给preLink函数。因此preLink中的element不是一个原始的html,而是一个element实例,它拥有一个scope。一样的状况也在postLink之中。dom


一个元素的pre-link函数可以保证是运行在它全部的子指令的post-link与pre-link运行以前执行的。正如以前所说的通常这里就能够经过scope给子节点传递必定的信息。当运行包含子指令的指令post-link时,反向的post-link规则能够保证它的子指令的post-link是已经运行过的,这就是为何人们都认为post-link是最安全或者默认的写业务逻辑的地方.。
函数


参考连接:http://www.jb51.net/article/58229.htmpost

相关文章
相关标签/搜索