AngularJS Directives: Are Link and Compile functions meant to work together?

13,931

Solution 1

link and compile do not work together, no.

In the directive definition object, if you only define link, that's like shorthand for having an empty compile function with an empty preLink function with your code in the postLink function. As soon as you define compile, link is ignored by angular, because compile should return the linking functions.

If you only return one function from compile, then it'll be executed post link.

Or, put differently, link is just a shortcut to the postLink function that gets called after the scope has been linked by compile.

It's (sort of) documented here - look at the comments in the code sample.

Solution 2

A couple of days ago a nice article has been published by Jurgen Van de Moere on "The nitty-gritty of compile and link functions inside AngularJS directives". It explains quite clearly on the responsibilities and sequence of the compile, pre-link and post-link functions.


(source: jvandemo.com)

You should definitely check it out: http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives

Share:
13,931
jviotti
Author by

jviotti

Software Engineer at Balena.io.

Updated on June 05, 2022

Comments

  • jviotti
    jviotti about 2 years

    I have a few doubts about this functions.

    Lets say I have this directive:

    .directive('hello', function () {
        return {
          template: '<div>Hello <span ng-transclude></span></div>',
          restrict: 'E',
          transclude: true,
          compile: function() {
            console.log('Compile()');
    
            return {
              pre: function() {
                console.log('PreLink()');
              },
              post: function() {
                console.log('PostLink()');
              }
            };
          },
          link: function postLink(scope, element, attrs) {
            console.log('Link()');
          }
        };
      }
    

    And I add it to my template as:

    <hello>World</hello>
    

    The console logs:

    Compile()
    PreLink()
    PostLink()
    

    So why is the link() not being called?

    If instead of returning an object from compile() I return a single function printing PreLink() the console logs:

    Compile()
    PreLink()
    

    If I don't return anything from Compile() the console logs:

    Compile()
    

    Still link() is not being called.

    If I just comment Compile() then Link() is finally printed:

    Link()
    

    Can someone explain all this? Are Link() and Compile() mean to work together? Should I just use Compile's PreLink() and PostLink()?