AngularJS:ng-repeat的编译和链接功能

时间:2013-10-19 19:26:11

标签: angularjs angularjs-directive angularjs-ng-repeat

我正在尝试理解编译和链接功能之间的区别。在the compiler的角度文档中,它说

  

对于集合中的每个项目,一些指令(例如ng-repeat克隆DOM元素)一次。编译和链接阶段可以提高性能,因为克隆模板只需要编译一次,然后为每个克隆实例链接一次。

我查看source code以尝试了解其工作原理,但我不了解它如何为每个克隆实例创建单独的链接函数。对我来说,看起来编译函数为ng-repeat指令返回一个链接函数。此链接函数确实为ng-repeat中的每个元素创建了一个新范围,但没有为每个克隆实例提供单独的链接函数。

2 个答案:

答案 0 :(得分:6)

他们的描述可能令人困惑的一件事是他们试图在<ng-repeat>内讨论指令的想法,而不是讨论<ng-repeat>本身。

这个想法是即使你有一个特定指令的多个实例(例如因为它们在<ng-repeat>内),编译函数只会在你的应用程序的生命周期内执行一次而且只执行一次。因此,在此处放置代码的性能优势是它只能运行一次。这也是潜在的问题。在编译函数中应该进行的唯一事情是该指令的所有实例化都是通用的。

另一方面,链接函数对于该指令的每个实例化执行一次(例如,在<ng-repeat>内)。

因此,您可以将编译函数视为设置此类型的指令应该是什么的模板,而link函数则设置该指令的实际实例。这就是链接函数传递给它的$ scope和编译没有的原因以及链接函数为什么更常用的原因。

要获得Angular的一位作者的详细讨论,请查看:http://www.youtube.com/watch?v=WqmeI5fZcho&list=TLwY_LmqLDXW_3QKhTNm1zKa9j40TvPO2O(13:42是Misko地址链接与编译功能的对象)

答案 1 :(得分:2)

除了KayakDave的答案之外,这里还有一个简单的ng-repeat实现,它没有进行任何收集观看。 plunker具有显示事件序列的日志记录,甚至还有一些显示优先级如何工作的示例。

Plunker

Link to source question

使用Javascript:

app.directive('fakeRepeat', function() {
  return {
    priority: 1000,
    terminal: true,
    transclude: 'element',
    compile: function(el, attr, linker) {
      return function(scope, $element, $attr) {
        angular.forEach(scope.$eval($attr.fakeRepeat).reverse(), function(x) {
          var child = scope.$new();
          child[attr.binding] = x;
          linker(child, function(clone) {
            $element.after(clone);
          });
        });
      }
    }
  }
});