Search code examples
angularjsangularjs-directiveangularjs-ng-transclude

When does transclusion take place in the compilation/linking process of a directive's setup?


I'm writing a custom directive that uses transclusion. I need to make modifications to the transcluded DOM content AFTER the transclusion has taken place....would I want to do that in the post-link or in the controller or ... the link...? I don't know where transclusion falls in the order of those things happening, so I don't know how to ensure my JS is executed after the transclusion has taken place.


Solution

  • The transclusion takes place during the compilation phase. Angular's $compile service goes over the DOM, and if a directive has transclusion enabled, Angular extracts the contents of the element (if transclude: true, or the element itself - for transclude: 'element'), compiles them, and makes the compiled content available in the transclusion function, bound to the transclusion scope.

    So, the order of execution would be:

    1. Angular transcludes the contents and compiles it: compile functions of the transcluded content directives execute
    2. compile function of the directive executes - returns pre- and post-link functions
    3. controller function of the directive executes
    4. pre-link function of the directive executes
    5. post-link function of the directive executes.

    You may decide to execute the transclude function in the post-link function. As soon as you do,

    1. controller, pre-, and post-link functions of the transcluded content directives execute

    transclude function is available at step #3-#5, and when invoked, it provides a fresh copy of the transcluded element to the cloneAttachFn, which you provide as a parameter to the transclude function:

    link: function(scope, element, attrs, ctrls, transclude){
        transclude(scope, function cloneAttachFn(clone){
          // you can do DOM manipulation of the clone instance here
        });
    }
    

    Note, that the DOM manipulation in the cloneAttachFn would apply to an instance of the transcluded DOM - not to the pre-compiled DOM template.