Difference between ngInclude and ngBindHtml - html

What is the difference between ng-include and ng-bind-html in angular??
imagine a case when based on some parameters the html will change rather to be for example an image tag or span tag; so There should be a mechanism to add that dynamic html
for example
<!--dynamichtml : <span class='glyphicon glyphicon-plus'></span>-->
<a ng-include="'dynamichtml.html'"></a>
<a ng-bind-html="dynamichtml"></a>

ng-bind-html is described as follows:
Evaluates the expression and inserts the resulting HTML into the element[...]
ng-include, on the other hand
Fetches, compiles and includes an external HTML fragment.
The value in ng-bind-html should evaluate to valid HTML. The value in ng-include should evaluate to a valid URL.

ng-bind-html
ng-bind-html is used when one has a model that contains HTML in the string format. On binding the model with that of the DOM, this gets updated in the element, as its child.
ng-include
This adds an external html file in the DOM. Here, it doesn't gets bind, but only gets attached.
It depends upon the application and the model states, based on which one can decide with which directive to make use of.
Here, you can read more about ng-bind-html and ng-include.

Related

Angular 5 - Bind a component selector with InnerHtml

I have a component1 selector that I called "app-component1".
#Component({
selector: 'app-component1',
templateUrl: './test-widget.component.html',
styleUrls: ['./test-widget.component.scss'] })
So to call the html of this component I usually use:
<app-component1></app-component1>
and it works perfectly fine.
Now from another component2 I have the following variable:
variableToBind = "<app-component1></app-component1>";
And In the html of component 2 I used the following:
<div [innerHtml]="varibableToBind"></div>
The html code binding isn't working. Is is possible to help me understand why and maybe help me find another alternative?
Thanks Everyone for the suggestions, I actually just find the answer to this:
This can't work because innerHtml is rendered AFTER Angular's compiled the templates. That means that it doesn't understand your selectors at this point of time.
If you guys want to load a component (or any content) dynamically, you should use *ngIf. It worked perfectly fine for me.
Angular sanitizes the HTML to prevent XSS attacks. You should find something like WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss). in your console output.
For further information, check out the documentation on property binding (esp. content security) and the security docs.
Depending on your use case, you need to choose another approach.
Your example code is not a valid approach as
1) html code cannot be bound to element property directly for security reason. ref: https://angular.io/guide/security#xss
2) There is no need to do property binding for HTML in your case. If you want to perform different logic inside AppComponent2, the best practice is to do property binding for the parameters that can customise component behaviours:
<div>
<app-component1 [prop1]="myVar1" [prop2]="myVar2"></app-component1>
</div>
and then you can customise it from the component properties instead of the component itself. This would make more sense.
If you really* need to pass HTML to component (for example if you have text with <br> tags or something like that), you can create custom Input like so:
export class YourComponent {
#Input() public htmlContent = '';
}
<div [innerHtml]="htmlDescription"></div>
And use it like so:
<your-component [htmlDescription]="textWithHtmlTags"></your-component>
* - for example if a string of text with basic HTML formatting tags (like <b>, <i> or even <br>) needs to be rendered.
In Angular, it is generally not recommended to bind a component selector using the [innerHTML] binding, because this can lead to security vulnerabilities. Instead, you should use Angular's template syntax and component structure to include components in your templates.
If you need to dynamically choose which component to include based on some condition, you can use the ngIf directive and the element to include a component only if a certain condition is met.
<ng-template [ngIf]="showMyComponent">
<my-component></my-component>
</ng-template>

AngularJS Directive once-style vs HTML global style attribute

Why would I use one over the other, except if I need to define the style from a function?
<div once-style="{width:50%;}"/>
once-style
<div style="width:50%;"/>
HTML Style Attribute
If i have a fixed style in an AngularJS application is there a reason to use one over the other?
I tried finding relevant information, i just found this which really didn't answer my question.
One time binding is native to Angular. Inside the curly braces prefix the expression with a double colon. For example:
{{::name}}

Is there a way to safely hide HTML tags in AngularJS?

I'm recently starting to explore AngularJS, and of course, i know it is ran at the client side, and since SPA (Single Page Applications) are becoming more and more common, i have a question regarding how to safely hide HTML elements.
Let me give a simple example:
Employee
<div ng-show="canSeeSalary">
{{salary}}
</div>
Now, of course, at runtime the div tag related to the salary won't be displayed, however by seeing the HTML source code, or using a developer tool like the one we have in Chrome, it would be possible to see the tag and probably its value.
I know tags like these should be filtered at the the server-side, of course, but since it has come to the client side, the div will be there.
My question is exactly, if there is any way i could hide these divs from the HTML source code, without needing to mix AngularJS with JSTL, for example.
Thanks in advance.
Try ng-if directive:
<div ng-if="canSeeSalary">
{{salary}}
</div>
Corresponding div element will be removed from the DOM. From the official documentation:
The ngIf directive removes or recreates a portion of the DOM tree
based on an {expression}. If the expression assigned to ngIf evaluates
to a false value then the element is removed from the DOM, otherwise a
clone of the element is reinserted into the DOM.
Use
Employee
<div ng-if="canSeeSalary">
{{salary}}
</div>
ng-if completely removes and recreates the element in the DOM rather than changing its visibility via the display css property
I would recommend using ngCloak rather than ngIf.
The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display.
example:
<div ng-cloak> {{::test}} </div>
ngCloak # Official Angular Docs

How to print html from angularjs expression?

Lets suppose I want to print the following html:
<a href..?> </a>
and I have it inside some expression.
how can I print it so it will be clickable using {{x.something}} in angular js ng-repeat?
You can do 1 of 2 things.
Use $sce service with the ng-bind-html attribute. $sce requires that you call $sce.trustAsHtml() around the html content before binding to the UI.
Use ngSanitize (by adding it as a dependent module) and then use ng-bind-html

Xpath and innerHTML

What Xpath expression can I use to find all the anchor (just 'a') elements whose actual text (the innerHTML) is Logout.
something like
//a[#innerHTML='Logout']
Would that be correct?
No, it would be incorrect. innerHTML is a property, part of the object model, while XPath operates on tags and attributes. Unless your a tag actually has an attribute named innerHTML, this wouldn't work.
If you want to compare the value of the tag itself, you can use the . (dot) to refer to the tag:
a[.='Logout']
However, I must add, just in case you're using jQuery: I'm not sure if it will work with jQuery. jQuery does not support XPath fully, only basic stuff.