Basic Difference Between transclude : true and replace: true in Angular Js - javascript

Hey I am new to angular js , So i was going through the angular js.org docs for making a custom directive.I wanted to know the basic difference between transclude and replace.
I have seen few examples where in they have used transclude: true and replace: true for a custom directive.
Sorry if it's a basic question in angular js . Just making my basics clear.

When you use transclude, you are including any html that is available inside your custom tags on your page. For example, if you had:
<person><p>some text</p></person>
the paragraph tag would be included in the spot where you have:
template: '<div ng-transclude></div>',
so your output to the page would read:
<div><p>some text</p></div>
The replace:true just means that the output in your template completely replaces the html on your page. So you would no longer see the tags (for example if you looked at the html source code). If you don't use repace:true, what you see on the screen is the same, but if you look at your html output you will see info about your own tags.
Without replace the html output would be this:
<person class="ng-isolate-scope"><div ng-transclude=""><p class="ng-scope">some text</p></div></person>
With replace the html output would be this:
<div ng-transclude="" class="ng-isolate-scope"><p class="ng-scope">some text</p></div>

Related

Transclude example not working for me

I've been taking a look for this tutorial, and now I'm trying to follow it. But somehow, when I reach the following JSBin and paste it all on my test folder, it just won't work:
http://teropa.info/blog/2015/06/09/transclusion.html
You can see at the right side the card showing up perfectly. Well, when I copy paste this code, the content doesn't get rendered inside the "content" div of the template, which means that transclusion isn't working at all.
What may be happening? The code is perfectly pasted, both HTML, CSS and JS. Even tried with my local version of Angular (last one).
But the content keeps being hidden! Any help with this? I really wanna learn how the transclusion works.
Consider I have created a directive called myDirective as an element
<div ng-controller="myCtrl">
<my-directive>
<button>some button</button>
and a link
</my-directive>
</div>
myDirective has a template which is using transclude
myApp.directive('myDirective', function(){
return{
restrict: 'E',
transclude: true,
template: '<div class="something" ng-transclude> my directive goes here...</div>'
}
});
It will render the DOM as
<div class="something">
my directive goes here...
<button>some button</button>
and a link
</div>.

How setup template file for chart tooltip?

I use angularJS and kendo.
How setup template (separated) for chart tooltip ?
<div id="buildLogChart" kendo-chart
k-tooltip="{ visible: true, template: '#TooltipTemplate' }">
</div>
You can use k-tooltip="tooltipOptions" where on your controller define $scope.tooltipOptions then you can simply set the template from your controller like for example
$scope.tooltipOptions = {
visible :true,
template : "<div id='testId' class='testClass' style='font-size:15px;'>\
<div>${series.name}</div>\
<div>${series.color}</div>\
<div>${value}</div>\
</div>"
};
Explanation :
You can pretty much use id class or inline css to suit your styling(the content of the tooltip)
needs
The list of information you can acess from within is listed here
Dont forget to add '\' if you intend to create a multiline otherwise
you need to finish it in 1 line(bad for readabilty though)
And Finally here's
DEMO
Also if you want to put it on separate file (i'm not sure if i got your question 100%), you can use kendo template by creating a page and add a kendo template script
<script id="customTooltipTemplate" type="text/x-kendo-template">
<div id='testId' class='testClass' style='font-size:15px; color:black; background-color:white;'>
<div>${series.name}</div>
<div>${series.color}</div>
<div>${value}</div>
</div>
</script>
Then import/link the file to your controller then you can use it like :
$scope.tooltipOptions = {
visible :true,
template : kendo.template($("#customTooltipTemplate").html())
};
And Finally here's
DEMO
NOTE: i'm not creating it on a separate file because i obviously can't do it here on kendo dojo, but this kendo template can be placed on other page but you need to import/link the file to your current file first. Read more about kendo template here

Angularjs convert string to html in view

I am currently trying to add links in my view. I do have links which basically contains html tags as strings.
I tried:
<p data-ng-repeat='i in links' >{$ i.link $}</p>
which basically just deploy in my view : mylink
So I did try:
<p data-ng-repeat='i in links' ><span data-ng-bind-html="i.link"></span></p>
It doesn't work though, any idea how could I achieve this ?
Thanks.
Add the $sce as a dependancy of the module
angular.module('myApp', ['$sce']);
When getting the links
angular.forEach($scope.links, function(value){
value.link = $sce.trustAsHtml(value.link);
});
Using Safe Contextual Escaping (docs.angularjs.org/api/ng/service/$sce) and using trustAs delegate you're telling Angular that this value is safe to use within that context. In this example. $sce.trustAsHtml returns an object that angular can trust is safe to as HTML.
In the first case, you'll actually want to use:
<p data-ng-repeat='i in links' >{{ i.link }}</p>
Double braces, not brace-dollar. In the second case, ng-bind-html will require that you have added "ngSanitize" to your module's dependency list.
angular.module('yourAppNameHere', ['ngSanitize'])
Edit:
If you really do want clickable links on the page, then do pretty much what #sreeramu suggested (Though I'd see if you can't find a way to add a nice description):
<p data-ng-repeat='i in links' ><a ng-href="{{i.link}}">{{i.desc}}</a></p>
(Notice that he suggested using ng-href, instead of href. He's right.)
Insert ngSanitize as a dependency to you app:
angular.module('myApp', ['ngSanitize'])
But before be ensure that you are including the script angular-sanitize.js.
Good luck!
It might be that your links have already got the a tags with it so in this case you do not need to re-add the a tags...
In this case do this...
Add this to you scripts (include acc. to your angular version)
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-
sanitize.min.js"></script>
Add this to your app.js
var app = angular.module('modulename', [ 'ngSanitize']);
And than in your view do this
If it is the div that you want the link to attach to...
<div ng-bind-html="i.link"></div>
The above would give you something as this
<div><a href='your link'></a></div>

Why does angular differentiate between `<my-element></my-element>` and `<my-element />`?

I just discovered a weird issue with Angular 1.2.1, demonstrated in this fiddle (tested in both IE, FF, and Chrome): if I create a very simple templated directive, it fails to work as <my-element /> if it hasn't first been used as <my-element></my-element>.
This is the js code from the fiddle in its entirety:
angular.module('app', []);
angular.module('app').directive('myElement', function() {
return {
restrict: 'E',
replace: true,
template: '<p>Hello, element!</p>'
};
});
and the html:
<div ng-app="app">
<my-element />
<my-element></my-element>
</div>
The output I expect from that is two paragraphs with the contents Hello, element!, but I only get one. If, however, I reverse the order of the two <my-element>-tags, so that the self-closing one comes after, both of them give output.
Why does Angular behave in this pathological way?
Your own self-closed tag should not be used
The browser interprets if a tag is "self-closeable" or not.
It doesn't know your tag as "self-closeable" (he knows only the HTML tags) and this is why it has a strange behavior.
On www.w3.org you can find the Elements section:
A void element is an element whose content model never allows it to have contents under any circumstances.
The following is a complete list of the void elements in HTML:
area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr
A non-void element must have an end tag, unless the subsection for that element in the HTML elements section of this reference indicates that its end tag can be omitted....
So, the conclusion is: don't use the short form for your own tag.
Interpreting your own self-closed tag in browser
That strange behavior appears because the browser interprets a self-closed tag like a parent of all siblings that come after it.
Let's ignore the AngularJS for the moment, and let's consider 3 new tags that are not in HTML: <x>, <y> and <z>.
E.g.:
<x></x>
<y></y>
<z></z>
will appear in the source code (F12 in Chrome) as they are.
But
<x></x>
<y/>
<z></z>
will look like:
<x></x>
<y>
<z></z>
</y>
Now, they we have this information, let's come back to AngularJS:
<my-element />
<my-element></my-element>
becomes
<my-element>
<my-element></my-element>
</my-element>
and the "main" = parent <my-element> is found and replaced by <p>Hello, element!</p>. => one output line => in this case you can also have some text or other tags after the 2nd line of code, because they will be wrapped in the parent and the result will be the same.
But, on the other hand:
<my-element></my-element>
<my-element />
will become
<my-element></my-element>
<my-element></my-element>
that will be displayed 2 times.
Here is the issue :-
https://github.com/angular/angular.js/issues/1237
In HTML there is no such thing as a self closing tag. There are only tags which are leafs. Leaf tags are fixed.
As an addition to earlier answers, this will give a better idea on what's happening. Run this in jsfiddle.
The self closing tag is assumed to be the starting tag and all the text following is thought of as directive's content.
angular.module('app', []);
angular.module('app')
.directive('myElement', function () {
return {
restrict: 'E',
transclude: true,
scope: {},
template: '<p>Hello, <span ng-transclude></span> element!</p>'
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app="app">
<my-element/>
<my-element>jfdsfkl</my-element>
<my-element>jfdsfkl</my-element>
<my-element/>
<my-element>jfdsfkl</my-element>
</div>

How to dynamically nest directives in AngularJS

New to Angular and need some assistance.
I have a block of HTML content that will be coming from a database that will contain a group of widgets. These are simple widgets that will essentially render out various elements, but for the purposes of this question we'll assume they're all basic HTML inside.
Those widgets are included in an unpredictable way, so my first thought was to use directives to render the HTML. So, we'd have something like:
<div widget data="This is the content."></div>
So I've got a directive that will place the value of data into the div. Easy enough!
Now, how would I go about nesting those widgets? So, how would I get something like:
<div widget data="Welcome! ">
<div widget data="This is some inside content."></div>
</div>
to render out:
Welcome! This is some inside content.
... because the issue I'm noticing is that if I place anything inside the directive HTML, it essentially gets ignored since it gets replaced with its own result (thus only echoing out Welcome!).
I realize I may be going the wrong direction on this in the first place, so any insight would be greatly appreciated. Thanks so much!
This is where you need to use the transclusion feature of the directive combined with ng-transclude directive.
Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
Any existing content of the element that this directive is placed on will be removed before the transcluded content is inserted.
A very basic version of transclusion of content based on your example might look something like this:
.directive('widget', function() {
return {
transclude: true,//Set transclusion
template: '{{text}} <section ng-transclude></section>', <!-- set where you need to present the transcluded content -->
scope: {
text: "#"
}
}
});
Demo
angular.module('app', []).directive('widget', function() {
return {
transclude: true,
template: '{{text}} <section ng-transclude></section>',
scope: {
text: "#"
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<span widget data-text="Welcome! ">
<div widget data-text="This is some inside content.">
<span widget data-text="This is some inside inside content."></span>
</div>
</span>
</div>

Categories

Resources