angularjs指令中的compile与link函数详解(2)


 // COMPILE PHASE
    // levelOne:    compile function is called
    // levelTwo:    compile function is called
    // levelThree:  compile function is called

// PRE-LINK PHASE
    // levelOne:    pre link function is called
    // levelTwo:    pre link function is called
    // levelThree:  pre link function is called

// POST-LINK PHASE (Notice the reverse order)
    // levelThree:  post link function is called
    // levelTwo:    post link function is called
    // levelOne:    post link function is called

这个例子清晰的显示出了ng在link之前编译所有的指令,然后link要又分为了pre-link与post-link阶段.

注意下,compile与pre-link的执行顺序是依次执行的,但是post-link正好相反.

所以上面已经明确标识出了不同的阶段,但是compile与pre-link有什么区别呢,都是相同的执行顺序,为什么还要分成两个不同的函数呢?

DOM

为了挖的更深一点,让我们简单的修改一下上面的代码,它也会在各个函数里打印参数列表中的element变量

复制代码 代码如下:


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'));

注意下console.log里的输出,除了输出原始的html标记基本没别的改变.

这个应该能够加深我们对于这些函数上下文的理解.

再次运行代码看看

输出

下面是一个在控制台输出结果的截图

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

假如你还想自己运行看看效果,可以点击this plnkr,然后在控制台里查看输出结果.

观察

输出dom的结果可以暴露一些有趣的事情:dom内容在compile与pre-link两个函数中是不一样的

所以发生了什么呢?

Compile

我们已经知道当ng发现dom构建完成时就开始处理dom.

所以当ng在遍历dom的时候,碰到level-one元素,从它的定义那里了解到,要执行一些必要的函数

因为compile函数定义在level-one指令的指令对象里,所以它会被调用并传递一个element对象作为它的参数

如果你仔细观察,就会看到,浏览器创建这个element对象时,仍然是最原始的html标记

1.在ng中,原始dom通常用来标识template element,所以我在定义compile函数参数时就用到了tElem名字,这个变量指向的就是template element.

一旦运行levelone指令中的compile函数,ng就会递归深度遍历它的dom节点,然后在level-two与level-three上面重复这些操作.

Post-link

深入了解pre-link函数之前,让我们来看看post-link函数.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgsygx.html