AngularJS: compilation functions and ng-repeat links

I am trying to understand the difference between a compilation function and a link. The angular documentation for the compiler says:

Some directives, such as the ng-repeat clone DOM elements for each element in the collection. Having a compilation phase and a link improves performance because the cloned template only needs to be compiled once and then linked once for each clone instance.

I looked at the source code to try to understand how this works, and I don’t understand how it creates a separate binding function for each cloned instance. For me, it looks like the compilation function returns one binding function for the ng-repeat directive. This bind function creates a new area for each element in ng-repeat, but does not give each cloned instance a separate bind function.

+7
angularjs angularjs-ng-repeat angularjs-directive
source share
2 answers

One thing that may confuse their description is that they are trying to discuss the idea of ​​a directive in <ng-repeat> , rather than discussing <ng-repeat> .

The idea is that even if you have several instances of a particular directive (for example, because they are within the <ng-repeat> ), the compilation function is executed once and only once for the life of your application. Thus, the advantage of using code here is that it runs only once. And this is also a potential problem. The only thing that should go into the compilation function is things that are common to all instances of this directive.

The link function, on the other hand, is executed once for each instance of this directive (again, for example, within <ng-repeat> ).

So, you can think of the compilation function as setting up a template of what should be a directive of this type, while the link function sets up the actual instance of this directive. This is why the link function gets the $ scope passed to it, and the compilation does not work, and why the link function is much more often used.

For an excellent discussion of exactly this by one of the authors of Angular, check: http://www.youtube.com/watch?v=WqmeI5fZcho&list=TLwY_LmqLDXW_3QKhTNm1zKa9j40TvPO2O (13:42 is where Misko is the link address and compilation functions)

+6
source share

In addition to answering KayakDave, this is a simple ng-repeat implementation that does not take any observations on the collection. The plunker has a log that shows the sequence of events and even has some examples showing how priority works.

Plunker

Link to the original 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); }); }); } } } }); 
+2
source share

All Articles