Do you use link functions in Angular directives? Me too. But sometimes that’s not always the best tool for the job.

In my case, I’m working with a third party directive (namely, Angular Ui Grid). Angular UI grid doesn’t provide a server side implementation for filtering and sorting and so I wanted to add it. The catch is that I needed to add this functionality before the ui-grid directive was initialized (that’s just the nature of this particular directive). Because link functions are treated as post functions, the ui-grid directive was compiled before my wrapper had a chance to add this functionality.

For a fantastic explanation of the difference between link, compile, pre, and post, I recommend this (yes this is a cop-out). To summarize, in case you’re too lazy to read that: Pre and post links are useful when you have directives nested inside directives and you want you want to run code in the parent directive before the child directive gets compiled.

NOTE: Angular treats link functions in directives as post functions.

For example, if you the following nested directives:

  <alpha>
    <beta></beta>
  </alpha>

If you use post function (or link function), beta will compile and run it’s post function and then alpha will follow suit. If I wanted beta to read configuration generated by alpha, I can’t.

The solution is to instead of using the link function that many of us automatically default to, to instead use a compile function:

app.directive("simple", function(){
   return {
     restrict: "EA",
     transclude:true,
     template:"<div><div ng-transclude></div></div>",
 
     compile: function(element, attributes){
 
         return {
             pre: function(scope, element, attributes, controller, transcludeFn){
 
             },
             post: function(scope, element, attributes, controller, transcludeFn){
 
             }
         }
     }
   };
});

If you want something in alpha to run before beta, put that code in alpha’s pre function. When the directives are compiled, they will be traversed down from top to bottom, which means the pre function in alpha will run and the the pre function in beta will run.

Then the directives are traversed from bottom to top, and the post functions are called. The post function in beta will be called before alpha.

In this was, I was able to add functionality to the ui-grid directive before it was initialized because I put the new configuration data in the pre function of the wrapper.