Understanding transclusion in AngularJS

Of all the concepts in AngularJS, many developers find transclusion to be complex and difficult to understand. In this post, let’s take a deep dive into it with a simple example.

The document from http://docs.angularjs.org/guide/directive says:

transclude – compile the content of the element and make it available to the directive. Typically used with ngTransclude. The advantage of transclusion is that the linking function receives a transclusion function which is pre-bound to the correct scope. In a typical setup the widget creates an isolate scope, but the transclusion is not a child, but a sibling of the isolate scope. This makes it possible for the widget to have private state, and the transclusion to be bound to the parent (pre-isolate) scope.

  • true – transclude the content of the directive.
  • ‘element’ – transclude the whole element including any directives defined at lower priority.

To understand the above, lets consider a simple directive called sampleDirective that is applied on an element. The element has some content within it like:

If sampleDirective is using a template, we will notice that the content of <div sample-directive> will be replaced by the directive template. So having:

will result in the following:

Notice that the content of original element <div sample-directive> will be lost (replaced).

So, what if you want to keep your <button>... and <a href>... in the DOM? You’ll need something called transclusion. Transclusion is about injecting the content from one place into another. So now your directive will look something like this:

This would render:

So, basically we use transclude when we are using a directive and want to preserve the contents of the element on which it is applied.

With AngularJS version >= 1.2.9. The content from the template is not appended but completely replaced.

So in the above example, what you would achieve with ‘transclude’ would be:

and not

But, if you still want to have all the content, you can achieve that by including in your template a simple container tag (like div or span) with the ng-transclude attribute. This means that the following code in your template should include all content

 

Leave a Reply

Top