Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular directives - when and how to use compile, controller, pre-link and post-link [closed]

When writing an Angular directive, one can use any of the following functions to manipulate the DOM behaviour, contents and look of the element on which the directive is declared:

  • compile
  • controller
  • pre-link
  • post-link

There seem to be some confusion as for which function should one use. This question covers:

Directive basics

  • How to declare the various functions?
  • What is the difference between a source template and an instance template?
  • In which order the directive functions are executed?
  • What else happens between these function calls?

Function nature, do's and dont's

  • Compile
  • Controller
  • Pre-link
  • Post-link

Related questions:

  • Directive: link vs compile vs controller.
  • Difference between the 'controller', 'link' and 'compile' functions when defining an angular.js directive.
  • What is the difference between compile and link function in angularjs.
  • Difference between the pre-compile and post-compile element in AngularJS directives?.
  • Angular JS Directive - Template, compile or link?.
  • post link vs pre link in Angular js directives.
like image 885
Izhaki Avatar asked Jul 07 '14 16:07

Izhaki


People also ask

What is compile pre and post linking AngularJS?

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.

How directives are compiled?

Each directive's compile function is only called once, when Angular bootstraps. Officially, this is the place to perform (source) template manipulations that do not involve scope or data binding. The <my-raw> directive will render a particular set of DOM markup.

What is the difference between link and compile in Angular JS?

Link function: It is used for registering DOM listeners as well as instance DOM manipulation. It is executed once the template has been cloned. Compile: traverse the DOM and collect all of the directives.

What is the difference between controller and link in directives?

Answer:The link option is just a shortcut to setting up a post-link function. controller: The directive controller can be passed to another directive linking/compiling phase. It can be injected into other directices as a mean to use in inter-directive communication.


1 Answers

How to declare the various functions?

Compile, Controller, Pre-link & Post-link

If one is to use all four function, the directive will follow this form:

myApp.directive( 'myDirective', function () {
    return {
        restrict: 'EA',
        controller: function( $scope, $element, $attrs, $transclude ) {
            // Controller code goes here.
        },
        compile: function compile( tElement, tAttributes, transcludeFn ) {
            // Compile code goes here.
            return {
                pre: function preLink( scope, element, attributes, controller, transcludeFn ) {
                    // Pre-link code goes here
                },
                post: function postLink( scope, element, attributes, controller, transcludeFn ) {
                    // Post-link code goes here
                }
            };
        }
    };  
});

Notice that compile returns an object containing both the pre-link and post-link functions; in Angular lingo we say the compile function returns a template function.

Compile, Controller & Post-link

If pre-link isn't necessary, the compile function can simply return the post-link function instead of a definition object, like so:

myApp.directive( 'myDirective', function () {
    return {
        restrict: 'EA',
        controller: function( $scope, $element, $attrs, $transclude ) {
            // Controller code goes here.
        },
        compile: function compile( tElement, tAttributes, transcludeFn ) {
            // Compile code goes here.
            return function postLink( scope, element, attributes, controller, transcludeFn ) {
                    // Post-link code goes here                 
            };
        }
    };  
});

Sometimes, one wishes to add a compile method, after the (post) link method was defined. For this, one can use:

myApp.directive( 'myDirective', function () {
    return {
        restrict: 'EA',
        controller: function( $scope, $element, $attrs, $transclude ) {
            // Controller code goes here.
        },
        compile: function compile( tElement, tAttributes, transcludeFn ) {
            // Compile code goes here.

            return this.link;
        },
        link: function( scope, element, attributes, controller, transcludeFn ) {
            // Post-link code goes here
        }

    };  
});

Controller & Post-link

If no compile function is needed, one can skip its declaration altogether and provide the post-link function under the link property of the directive's configuration object:

myApp.directive( 'myDirective', function () {
    return {
        restrict: 'EA',
        controller: function( $scope, $element, $attrs, $transclude ) {
            // Controller code goes here.
        },
        link: function postLink( scope, element, attributes, controller, transcludeFn ) {
                // Post-link code goes here                 
        },          
    };  
});

No controller

In any of the examples above, one can simply remove the controller function if not needed. So for instance, if only post-link function is needed, one can use:

myApp.directive( 'myDirective', function () {
    return {
        restrict: 'EA',
        link: function postLink( scope, element, attributes, controller, transcludeFn ) {
                // Post-link code goes here                 
        },          
    };  
});
like image 123
Izhaki Avatar answered Oct 19 '22 00:10

Izhaki