When shall we use `preLink` of directive's compile function?

10,685

Solution 1

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

Solution 2

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.

Solution 3

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.

Share:
10,685
Freewind
Author by

Freewind

A programmer ([email protected])

Updated on June 07, 2022

Comments

  • Freewind
    Freewind about 2 years

    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?

  • Freewind
    Freewind almost 6 years
    Could you give some sample demo code to show what you have done in preLink?