37

The compile function of angularjs' directive has two functions: preLink and postLink.

Pre-linking function

Executed before the child elements are linked. Not safe to do DOM transformation since the compiler linking function will fail to locate the correct elements for linking.

Post-linking function

Executed after the child elements are linked. It is safe to do DOM transformation in the post-linking function.

It tells what we should not do in preLink, I wonder what and when should I use preLink? For most of time I just used postLink. Is there any case that we must use it?

Community
  • 1
  • 1
Freewind
  • 193,756
  • 157
  • 432
  • 708
  • Yes, it seems like preLink is a redundancy of controller (except that preLink cannot be shared). – Jakob Jingleheimer Apr 18 '13 at 20:49
  • 4
    it seems that in angularjs core, `pre` is only used in `ngInit` (evaluates the expression before entering post-linking phase) and `form` directive. – g00fy Apr 24 '13 at 11:30
  • 2
    I found a good use-case for it here: [How to render a partial with variables](http://stackoverflow.com/questions/17863732/angularjs-how-to-render-a-partial-with-variables), though I'm pretty sure I could have used it as a postLink function interchangeably. – colllin Jul 28 '13 at 04:18
  • This might be helpful to you http://www.undefinednull.com/2014/07/07/practical-guide-to-prelink-postlink-and-controller-methods-of-angular-directives/ – Shidhin Cr Jul 26 '14 at 17:31

3 Answers3

13

You need almost never use preLink. Viable cases for it are when you need to manipulate data in scope, but not the DOM, before link functions (also of other directives) are executed.

As jacob commented, you can always do that from a controller too, but sometimes it's more appropriate to have the code in the directive itself.

There is an excellent article about how directives work where linking order is explained well to: http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives/

If you need a good example of why pre-linking is sometimes necessary, I recommend you look at the code of angular directives themselves. For example https://github.com/angular/angular.js/blob/master/src/ng/directive/ngModel.js

iwein
  • 25,788
  • 10
  • 70
  • 111
7

A preLink function is used when the directive wants to put something into a shared scope so that it's ready to be used by other directives in their postLink functions.

Angular's form directive, e.g., creates an object that contains entries for all inputs. A custom directive could safely access this object in a postLink function.

a better oliver
  • 26,330
  • 2
  • 58
  • 66
6

I've had to use preLink when creating custom directives which include other directives. In my case, my directive included a template which applied Angular UI Bootstrap's Typeahead directive to some of its elements and used its own scope variables to initialize Typeahead features.

For example:

...
template:
    "<select ng-show='dropdown' class='form-control' ng-model='ngModel' ng-options='s for s in suggestions'></select>"
    + "<textarea ng-show='!dropdown' class='form-control' ng-model='ngModel' typeahead='s for s in suggestions |filter:$viewValue' typeahead-min-length='0' typeahead-editable='{{editable}}'></textarea>",
...

In that case, Angular links the child directives before the parent, so I needed to use preLink to setup the typeahead. When I initialized the $scope.dropdown and $scope.editable variables in the directives postLink function, I found they were not initialized when the typeahead directives were linked and I had to move their initialization into the preLink to make this directive work correctly.

Derek
  • 1,466
  • 15
  • 24