Search code examples
javascriptangularjsangularjs-directiveangularjs-ng-transclude

Do something when nested/transcluded directives have been compiled and linked


Think about something like the following directive markup:

<!-- Directive A -->
<directive-a>
</directive-a>

<-- Directive B -->
<directive-b>
   <directive-a>
        <transclusion1></transclusion1>
   </directive-a>
</directive-b>

I need to perform some DOM manipulation once the <directive-a> has been already compiled+linked from <directive-b>.

When I provide a link function on <directive-b> (or compile function), <directive-a> is still without its transcluded content.

I can't figure out how to perform that DOM manipulation once the <directive-a> has been already compiled+linked.


Solution

  • Finally the solution is easier than I thought when I started to implement the solution.

    Let's say there's the <directive-a> with the following options:

    {
        scope: {
            "postLink": "&"
        }
    }
    

    ...and, as part of controller() function I do:

    {
        controller: () => {
            // Angular 1.5.3+
            this.$postLink = $scope.postLink;
        },
        scope: {
            "postLink": "&"
        }
    }
    

    Now I can hook to <directive-a> $postLink hook:

    <-- Directive B -->
    <directive-b>
       <directive-a post-link="model.directiveAPostLink()">
            <transclusion1></transclusion1>
       </directive-a>
    </directive-b>
    

    When the whole model.directiveAPostLink() function is called, <directive-a> is already compiled and linked!

    Further details

    Checking Angular GitHub's repository commit history, I've found the following description:

    $postLink - Called after this controller's element and its children been linked. Similar to the post-link function this hook can be used to set up DOM event handlers and do direct DOM manipulation.

    Note that child elements that contain templateUrl directives will not have been compiled and linked since they are waiting for their template to load asynchronously and their own compilation and linking has been suspended until that occurs.

    It's exactly my case: I'm loading templates from an URL.