Transclusion is no doubt a very confusing topic in AngularJS. It has two ways of implmentation :
1) transclude: 'true'
2) transclude: 'element'
as far as transclude: 'true' goes, one can grasp it with little effort but transclude: 'element' seems like a lot of work .
So, what thus transclude:'element' do ?
It transcludes the whole element ,i.e, it copies the content inside the directive as well as the directive tag itself and places one or more copies of it with the correct scope .
The transclusion is achieved via transclusion function unlike the more simpler ng-transclude in case of transclude: 'true' .
For a quick review of transclude:'true' , to achieve transclusion , we included <ng-transclude> wherever we wanted our element to appear inside the 'template' property like :
but when we do transclude: 'element', we cannot use a template , so we can't ng-transclude it , so instead, as i just mentioned , we will use transclusion function . Transclusion function is simply a link function , which is returned after compiling the transcluded elements .
To give you an overview of how transclusion is achieved by the browser, the flow is as follows :
So, basically , we are getting the contents of the element containing the directive which has transclusion enabled in the first line and storing them in a variable . Then we are removing the contents of the element from the DOM . In the third line , we are compiling the variable which has the contents of the element and producing the transclusion function (transcludeFn) .
This function is given as the fifth parameter of 'link' function . It was earlier used in 'compile' function as well but has become obsolete now .
This Transclude function can accept a scope and a call back function , and this function returns a clone of the transcluded element instead of the original element like :
This callback function is synchronous not asynchronous .
Now, its important to understand that this transcludeFn places the transcluded element and the location where you want to place can be achieved by Jquery style DOM traversal and modification . Like if i want to put the transcluded element after the 'element' , which is the second parameter of the link function , i can simply do :
Or i can attach a clone of the transcluded element to the DOM :
In the above two examples of transclusion, the transcluded elements get an inherited scope from the parent scope . Now there is an element of confusion here . The parent scope i am referring to is the original scope not the scope of the directive which has transclusion enabled.
Let me give an example :
suppose i have done transclude :element for my custom directive
note that i have isolated the scope of the directive , so in normal sense , anything inside this directive should not inherit from the parent controller scope
app.js :
and in my html
index.html:
{{$id}} is a very neat way to get the scope id .
{{$parent.$id}} gives the scope id of the parent scope .
i have used {{Var }} in the transcluded element , which is defined only in the parent controller .
So , now in my browser, i can see :
Did you see that , did you see that ? That guy is inheriting . 'Var' is being fetched from the parent controller 'mainController' , even though the directive has isolate scope . This behaviour of transclude element is desirable to avoid conflicts between scopes,scope leaking .
Now getting back to the features of transcludeFn , though the default scope of transcluded elements is like the one i mentioned above, you can also provide your own custom scope to it like :
so in the above case, i gave the first parameter as scope, which is also the first parameter of the link function , so you guessed it right , we are assigning it the scope of the custom directive . And since the directive has isolate scope, it will not read any properties from the parent scope and that {{Var}} should not evaluate , since it is not visible now to the transcluded element scope . Right? Yes ofcourse .
Our view is now :
Dont get confused by that line 'and i am inherited from : 2', since i used $parent in that and you can access the immediate parent in isolate scopes through $parent , which may sound confusing to some .
Now, lets talk something about the compiling and linking of transcludeFn .
when you do something like :
and when you do something like :
So, what is its importance . One is that, if you want to clone the transcluded element several times , like in the case of ng-repeat , you hve to insert the clones into html before linking . They will have individual scopes of their own , again like in ng-repeat ..
Lets further extend our app.js above
Here you can see we are doing five iterations of the for loop and embedding a clone in our html for each iteration . every clone has its own scope id.
Our view now :
This happens because we are inserting the html before linking, we wont be able to add clones, if we have already linked the element, like , if we do
we will only get a single element in our html :
Our view now :
There are many complex implementations of transclde: 'element' , but as an introduction and understanding to transclude: 'element' , this can get you going .
Cheers .
1) transclude: 'true'
2) transclude: 'element'
as far as transclude: 'true' goes, one can grasp it with little effort but transclude: 'element' seems like a lot of work .
So, what thus transclude:'element' do ?
It transcludes the whole element ,i.e, it copies the content inside the directive as well as the directive tag itself and places one or more copies of it with the correct scope .
The transclusion is achieved via transclusion function unlike the more simpler ng-transclude in case of transclude: 'true' .
For a quick review of transclude:'true' , to achieve transclusion , we included <ng-transclude> wherever we wanted our element to appear inside the 'template' property like :
transclude: 'true',template: '<some tags here><div ng-transclude><some tags here>',
but when we do transclude: 'element', we cannot use a template , so we can't ng-transclude it , so instead, as i just mentioned , we will use transclusion function . Transclusion function is simply a link function , which is returned after compiling the transcluded elements .
To give you an overview of how transclusion is achieved by the browser, the flow is as follows :
var elementsToTransclude = directiveElement.contents();
directiveElement.html(' ');
var transcludeFn= $compile(elementsToTransclude);
So, basically , we are getting the contents of the element containing the directive which has transclusion enabled in the first line and storing them in a variable . Then we are removing the contents of the element from the DOM . In the third line , we are compiling the variable which has the contents of the element and producing the transclusion function (transcludeFn) .
This function is given as the fifth parameter of 'link' function . It was earlier used in 'compile' function as well but has become obsolete now .
link : function(scope, element, attributes, controller, transcludeFn){}
This Transclude function can accept a scope and a call back function , and this function returns a clone of the transcluded element instead of the original element like :
transcludeFn(scope,function(clone){});
This callback function is synchronous not asynchronous .
Now, its important to understand that this transcludeFn places the transcluded element and the location where you want to place can be achieved by Jquery style DOM traversal and modification . Like if i want to put the transcluded element after the 'element' , which is the second parameter of the link function , i can simply do :
element.after(transcludeFn());
Or i can attach a clone of the transcluded element to the DOM :
transcludeFn(function(clone){
element.after(clone);
})
In the above two examples of transclusion, the transcluded elements get an inherited scope from the parent scope . Now there is an element of confusion here . The parent scope i am referring to is the original scope not the scope of the directive which has transclusion enabled.
Let me give an example :
suppose i have done transclude :element for my custom directive
note that i have isolated the scope of the directive , so in normal sense , anything inside this directive should not inherit from the parent controller scope
app.js :
var app=angular.module('mainModule',[]);
app.controller('mainController',function($scope){
$scope.Var='Hello I am you father';
});
app.directive('customDirective',function(){
return {
restrict: 'A',
scope: {},
transclude: 'element',
link: function(scope,element,attrs,controller,transcludeFn){
transcludeFn(function(clone){
element.after(clone);
});
}
}
});
and in my html
index.html:
<body ng-app="mainModule">
<div ng-controller="mainController">
Fathers scope is : {{$id}}
<div custom-directive>Hello People Socpe id is : {{$id}} and i am inherited from: {{$parent.$id}} {{Var}}</div>
</div>
</body>
{{$id}} is a very neat way to get the scope id .
{{$parent.$id}} gives the scope id of the parent scope .
i have used {{Var }} in the transcluded element , which is defined only in the parent controller .
So , now in my browser, i can see :
Fathers scope is : 2
Hello People scope id is: 4 and i am inherited from : 2 Hello i am your father .
Did you see that , did you see that ? That guy is inheriting . 'Var' is being fetched from the parent controller 'mainController' , even though the directive has isolate scope . This behaviour of transclude element is desirable to avoid conflicts between scopes,scope leaking .
Now getting back to the features of transcludeFn , though the default scope of transcluded elements is like the one i mentioned above, you can also provide your own custom scope to it like :
transcludeFn(scope,function(clone){});
so in the above case, i gave the first parameter as scope, which is also the first parameter of the link function , so you guessed it right , we are assigning it the scope of the custom directive . And since the directive has isolate scope, it will not read any properties from the parent scope and that {{Var}} should not evaluate , since it is not visible now to the transcluded element scope . Right? Yes ofcourse .
Our view is now :
Fathers scope is : 2
Hello People scope id is: 3 and i am inherited from : 2
Dont get confused by that line 'and i am inherited from : 2', since i used $parent in that and you can access the immediate parent in isolate scopes through $parent , which may sound confusing to some .
Now, lets talk something about the compiling and linking of transcludeFn .
when you do something like :
transcludeFn(scope, function(clone){element.after(clone) // this is compiled but not linked yet})
and when you do something like :
var transcluded=transcludeFn();element.after(transluded) // this is compiled and linked .
So, what is its importance . One is that, if you want to clone the transcluded element several times , like in the case of ng-repeat , you hve to insert the clones into html before linking . They will have individual scopes of their own , again like in ng-repeat ..
Lets further extend our app.js above
var app=angular.module('mainModule',[]);
app.controller('mainController',function($scope){
$scope.Var='Hello I am you father';
});
app.directive('customDirective',function(){
return {
restrict:'A',
scope:{},
transclude: 'element',
link: function(scope,element,attrs,controller,transcludeFn){
for (var i = 5; i >= 0; i--) {
trscluded=transcludeFn(function(clone){
element.after(clone);
});
}
}
}
});
Here you can see we are doing five iterations of the for loop and embedding a clone in our html for each iteration . every clone has its own scope id.
Our view now :
Fathers scope is :2Hello People Socpe id is : 8 and i am inherited from: 2 Hello I am you fatherHello People Socpe id is : 7 and i am inherited from: 2 Hello I am you fatherHello People Socpe id is : 6 and i am inherited from: 2 Hello I am you fatherHello People Socpe id is : 5 and i am inherited from: 2 Hello I am you fatherHello People Socpe id is : 4 and i am inherited from: 2 Hello I am you father
This happens because we are inserting the html before linking, we wont be able to add clones, if we have already linked the element, like , if we do
var app=angular.module('mainModule',[]);app.controller('mainController',function($scope){$scope.Var='Hello I am you father';});app.directive('customDirective',function(){return {restrict:'A',scope:{},transclude: 'element',link: function(scope,element,attrs,controller,transcludeFn){for (var i = 5; i >= 0; i--) {element.after(transcludeFn());}}}});
we will only get a single element in our html :
Our view now :
Fathers scope is :2Hello People Socpe id is : 8 and i am inherited from: 2 Hello I am you father
There are many complex implementations of transclde: 'element' , but as an introduction and understanding to transclude: 'element' , this can get you going .
Cheers .
transcludeFn(scope, function(clone){
ReplyDeleteelement.after(clone) // this is compiled but not linked yet
})
Nice catch, thanks!
You can specify that you want to insert a named transclusion slot, instead of the default slot, by providing the slot name as the value of the ng-transclude or ng-transclude-slot attribute.
ReplyDeleteIf the transcluded content is not empty (i.e. contains one or more DOM nodes, including whitespace text nodes), any existing content of this element will be removed before the transcluded content is inserted. If the transcluded content is empty (or only whitespace), the existing content is left intact. This lets you provide fallback content in the case that no transcluded content is provided.
AngularJS Certification Training in Chennai
Great post! I am actually getting ready to across this information, It’s very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
ReplyDeletejava training in tambaram | java training in velachery
java training in omr | oracle training in chennai
java training in annanagar | java training in chennai
You’ve written a really great article here. Your writing style makes this material easy to understand.. I agree with some of the many points you have made. Thank you for this is real thought-provoking content
ReplyDeletepython training in pune
python online training
python training in OMR
Excellent blog, I wish to share your post with my folks circle. It’s really helped me a lot, so keep sharing post like this
ReplyDeleteBlueprism training in Chennai
Blueprism online training
Blue Prism Training in Pune
I really like the dear information you offer in your articles. I’m able to bookmark your site and show the kids check out up here generally. Im fairly positive theyre likely to be informed a great deal of new stuff here than anyone
ReplyDeleteangularjs Training in chennai
angularjs-Training in chennai
angularjs Training in chennai
angularjs-Training in tambaram
angularjs-Training in sholinganallur
I am really happy with your blog because your article is very unique and powerful for new reader.
ReplyDeleteClick here:
selenium training in chennai
selenium training in bangalore
selenium training in Pune
selenium training in pune
Selenium Online Training
https://things-guide.blogspot.com/2014/02/Facebook-Like-Box-with-jQuery-Hover-Effect-for-Blogger.html
I am a regular reader of your blog and being students it is great to read that your responsibilities have not prevented you from continuing your study and other activities. Love
ReplyDeletedevops online training
aws online training
data science with python online training
data science online training
rpa online training
This comment has been removed by the author.
ReplyDeleteI am very interested to learn by seeing your blogs
ReplyDeleteAngularJS Training in Chennai | AngularJS Training in Anna Nagar | AngularJS Training in OMR | AngularJS Training in Porur | AngularJS Training in Tambaram | AngularJS Training in Velachery
Good to know about the email list business. I was looking for such a service for a long time o grow my local business but the rates that other companies were offering were not satisfactory. thanks
ReplyDeleteAi & Artificial Intelligence Course in Chennai
PHP Training in Chennai
Ethical Hacking Course in Chennai Blue Prism Training in Chennai
UiPath Training in Chennai
I have read this whole blog and it is an amazing blog for developers who are dealing daily with the new challenges and tasks.Thank You for sharing such a valuable, informative and useful thoughts for users in your blog.
ReplyDeleteOracle Training | Online Course | Certification in chennai | Oracle Training | Online Course | Certification in bangalore | Oracle Training | Online Course | Certification in hyderabad | Oracle Training | Online Course | Certification in pune | Oracle Training | Online Course | Certification in coimbatore
Great post you shared, you have now become top of my list. Thanks for your sharing!!
ReplyDeleteandroid training in chennai
android online training in chennai
android training in bangalore
android training in hyderabad
android Training in coimbatore
android training
android online training
Thanks for the informative article. This is one of the best resources I have found in quite some time. Nicely written and great info. I really cannot thank you enough for sharing.
ReplyDeletehadoop training in chennai
hadoop training in omr
salesforce training in chennai
salesforce training in omr
c and c plus plus course in chennai
c and c plus plus course in omr
machine learning training in chennai
machine learning training in omr
I really like your blog. You make it interesting to read and entertaining at the same time.
ReplyDeleteI cant wait to read more from you.keep it up!!!
web designing training in chennai
web designing training in tambaram
digital marketing training in chennai
digital marketing training in tambaram
rpa training in chennai
rpa training in tambaram
tally training in chennai
tally training in tambaram
It's interesting that many of the bloggers to helped clarify a few things for me as well as giving.
ReplyDeleteAngular js Training in Chennai
Angular js Training in Velachery
Angular js Training in Tambaram
Angular js Training in Porur
Angular js Training in Omr
Angular js Training in Annanagar
This article very precise. Can understand very easily. Thanks for sharing
ReplyDeleteSelenium Training in Chennai
Selenium Training in Velachery
Selenium Training in Tambaram
Selenium Training in Porur
Selenium Training in Omr
Selenium Training in Annanagar
Great post! I am actually getting ready to across this information, It’s very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
ReplyDeleteamazon web services aws training in chennai
microsoft azure training in chennai
workday training in chennai
android-training-in chennai
ios training in chennai
Whoa! I’m enjoying the template/theme of this website. It’s simple, yet effective. A lot of times it’s very hard to get that “perfect balance” between superb usability and visual appeal. I must say you’ve done a very good job with this.
ReplyDeleteIELTS Coaching in chennai
German Classes in Chennai
GRE Coaching Classes in Chennai
TOEFL Coaching in Chennai
Spoken english classes in chennai | Communication training
SMM PANEL
ReplyDeleteSmm panel
iş ilanları
İnstagram takipçi satın al
HIRDAVATÇI BURADA
beyazesyateknikservisi.com.tr
servis
tiktok jeton hilesi