Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the benefits of a directive template function in Angularjs?

According to the documentation a template can be a function which takes two parameters, an element and attributes and returns a string value representing the template. It replaces the current element with the contents of the HTML. The replacement process migrates all of the attributes and classes from the old element to the new one.

The compile function deals with transforming the template DOM. It takes three parameters, an element, attributes and transclude function. The transclude parameter has been deprecated. It returns a link function.

It appears that a template and a compile functions are very similar and can achieve the same goal. The template function defines a template and compile function modifies the template DOM. However, it can be done in the template function itself. I can't see why modify the template DOM outside the template function. And vice-versa if the DOM can be modified in the compile function then what's the need for a template function?

like image 353
Maksym Bykovskyy Avatar asked Jan 06 '14 01:01

Maksym Bykovskyy


People also ask

What is the use of directives in AngularJS?

AngularJS directives are extended HTML attributes with the prefix ng- . The ng-app directive initializes an AngularJS application. The ng-init directive initializes application data. The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.

What is Template directive in Angular?

What is meant by directives in Angular? Directives are classes that add new behavior or modify the existing behavior to the elements in the template. Basically directives are used to manipulate the DOM, for example adding/removing the element from DOM or changing the appearance of the DOM elements.


1 Answers

The compilation function can be used to change the DOM before the resulting template function is bound to the scope.

Consider the following example:

<div my-directive></div> 

You can use the compile function to change the template DOM like this:

app.directive('myDirective', function(){   return {      // Compile function acts on template DOM     // This happens before it is bound to the scope, so that is why no scope     // is injected     compile: function(tElem, tAttrs){        // This will change the markup before it is passed to the link function       // and the "another-directive" directive will also be processed by Angular       tElem.append('<div another-directive></div>');        // Link function acts on instance, not on template and is passed the scope       // to generate a dynamic view       return function(scope, iElem, iAttrs){          // When trying to add the same markup here, Angular will no longer         // process the "another-directive" directive since the compilation is         // already done and we're merely linking with the scope here         iElem.append('<div another-directive></div>');       }     }   } }); 

So you can use the compile function to change the template DOM to whatever you like if your directive requires it.

In most cases tElem and iElem will be the same DOM element, but sometimes it can be different if a directive clones the template to stamp out multiple copies (cf. ngRepeat).

Behind the scenes, Angular uses a 2-way rendering process (compile + link) to stamp out copies of a compiled piece of DOM, to prevent Angular from having to process (= parse directives) the same DOM over and over again for each instance in case the directive stamps out multiple clones resulting in much better performance.

Hope that helps!


ADDED AFTER COMMENT:

The difference between a template and compile function:

Template function

{     template: function(tElem, tAttrs){          // Generate string content that will be used by the template         // function to replace the innerHTML with or replace the         // complete markup with in case of 'replace:true'         return 'string to use as template';     } } 

Compile function

{     compile: function(tElem, tAttrs){          // Manipulate DOM of the element yourself         // and return linking function         return linkFn(){};     } } 

The template function is called before the compile function is called.

Although they can perform almost identical stuff and share the same 'signature', the key difference is that the return value of the template function will replace the content of the directive (or the complete directive markup if replace: true), while a compile function is expected to change the DOM programmatically and return a link function (or object with pre and post link function).

In that sense you can think of the template function as some kind of convenience function for not having to use the compile function if you simply need to replace the content with a string value.

Hope that helps!

like image 53
jvandemo Avatar answered Sep 19 '22 23:09

jvandemo