Martijn
Martijn

Reputation: 24799

Should you use the linking function over the compile function when you can in Angular?

I want to learn more about compile function and transclusion and found this Plnkr. This code contains a advanced tab directive. Based on this directive I started to create my own to see what happens and to see the values of the variables.

For my test I was playing with my 'button-bar'. When finished I had created this code:

testapp.directive('buttonBar', function($compile) {
    return {
        restrict: 'EA',
        compile: function(cElement){
            var title,
                template;

            template = "<div class='well'><div class='button-bar-title'></div></div>";
            title = cElement.find(".title");
            console.log("title:", title.html());

            return function(scope, element, attributes){
                var well = angular.element(template),
                    titleDiv = well.find(".button-bar-title");

                titleDiv.append(title.html());

                element.empty();
                element.append(well);

                $compile(titleDiv)(scope);

            }
        }
    };
});

Nothing fancy. But when I looked at the code, I thought, why use a compile function? I think I can refactor this using a link function, so I did:

testapp.directive('buttonBar', function($compile) {
    return {
        restrict: 'EA',
        link: function(scope, element, attributes){
            var title,
                template,
                well,
                titleDiv;

            template = "<div class='well'><div class='button-bar-title'></div></div>";
            title = element.find(".title");
            console.log("title:", title.html());

            well = angular.element(template),
            titleDiv = well.find(".button-bar-title");

            titleDiv.append(title.html());

            element.empty();
            element.append(well);

            $compile(titleDiv)(scope);
        }
    };
});

And this gave me the exact same result.

At this point I am confused, why should the originally author of the plunker use a compile function instead of a link function? Is there a good reason for? Or are there guidelines on when to use a compile or a link function?

Edit: For both directives I've used the same HTML (primary1Label is defined on the controller):

<button-bar>
    <div class="title">De titel is {{primary1Label}}</div>  
</button-bar>

Upvotes: 0

Views: 67

Answers (1)

eddiec
eddiec

Reputation: 7646

In the example you provided compile is the correct method, as it executes before the template is cloned and therefore performs less manipulation on the DOM.

The most fundamental difference between the two is that compile runs once for all directives on the DOM, whereas link runs for each individual element.

As a result it's recommended that if you want to perform a template DOM manipulation you should do so within the compile function.

If you want to listen to scope variables individually and perform instance DOM manipulation (i.e. on this element only) then the link function is what you want.

There's another answer here What is the difference between compile and link function in angularjs that explains it more thoroughly.

Upvotes: 1

Related Questions