Directive loaded from ng-bind-html doesn't execute [duplicate] - javascript

This question already has answers here:
angular ng-bind-html and directive within it
(6 answers)
Closed 6 years ago.
Inside the controller:
$scope.content = $sce.trustAsHtml('<some-directive></some-directive>');
The template:
<!-- Works perfectly -->
<some-directive></some-directive>
<!-- HTML loaded correctly, but the directive inside won't execute -->
<div class="article__main" ng-bind-html="content"></div>
What is going on here, exactly? How do I tell angular to check the DOM for new directives that are going to be added via ng-bind-html? BTW, I'm testing now and the directive is just logging to console, nothing else.
I used ng-include + a file on another version of the website (instead on ng-bind-html) and that worked.
Thanks on advance :)

You need to use the $compile Service.
var compiledTemplate = $compile(content)(scope);
You also have to define the parent scope.Here is the Doku to $compile
I never used it with ng-bind-html but setting it on the DOM with element.append() works just fine

Related

How to use *ngIf in index.html angular 8

How can I use *ngIf condition in index.html in Angular2+. I want to load tags based on condition using *ngIf for that I have a value in local storage. Here is my code but it is not working.
<head *ngIf="localStorage.getItem('theme_token') === 'site-layout'"></head
When I used script tag it get the value of theme token in javascript.
<script>
var _val = localStorage.getItem('theme_token'); /// This part is working returning me the value.
</script>
Note: I don't want to hide. I have to render it using *ngIf
condition.
*ngIf wouldn't do the trick for you. *ngIf will work inside angular. Try this example may this helps. It worked with angular 8. In your app component.
constructor() {
if (localStorage.getItem('theme_token') === 'site-layout') {
const temp = document.createElement('link');
temp.innerHTML = '<link id="default-css" href="assets/somestyle.css" rel="stylesheet" media="all">'
;
const head = document.head;
while (temp.firstChild) {
head.appendChild(temp.firstChild);
}
}
}
You can load according to your condition.
You can't use *ngIf outside . We have multiple ways to do the same in pure javascript. Go with vanila js for no side-effetcs.
As far as I am aware Angular application (most of them) has entry point of <app-root></app-root> where the application is bootstrapped, means from this point angular will come into the picture(memory) and then you have your routes, other components, angular stuff the way you have structured the application.
Now you want to use *ngIf in index.html, so point is where you will bind this index.html i.e. with which component to supply your *ngIf variable and even if you will just add *ngIf='true' it will be rendered as it is without any effect or side-effect
What you can do (possibly)
Try to do with plain JS via <scrip></script> access DOM, change it the way you want
If you want to do with Angular only, then in app.component.ts in ngOnInit access the DOM and do it.
Browser doesn't know what it has to with *ngIf, It is the angular that knows the meaning of *ngIf and this particular point angular not loaded yet

Pass html tag to angularjs variable from controller [duplicate]

This question already has answers here:
Insert HTML into view from AngularJS controller
(17 answers)
Closed 3 years ago.
I have this validations which I am trying to do every time user enters a wrong email. And I am handling it via variable in my html like this:
<p class="error" ng-show="!!user.errorText || form.$submitted">
{{user.errorText}}
</p>
So far everything is fine as I am replacing the errorText with text values from my controller like this:
$scope.user.errorText = "Email is incorrect"
Now, I actually wanted to insert a html tag like <a> . For example:
$scope.user.errorText = "Email is incorrect . <a href='#'>View Examples</a>"
But the vaiable {{user.errorText}} is always redering it as text. Any help on how can I render both tags and text would be helpful. Also, I can't replace {{user.errorText}} in html as it has already been in use for n number of validations and the scenario of using a html tag is rare.
You can use ng-bind-html directive to bind html text (it will work also for simple text):
<p ng-bind-html="user.errorText"></p>
https://docs.angularjs.org/api/ng/directive/ngBindHtml
If angular-sanitize.js is not included in the application, then the following error will show up:
angular.min.js:1 Error: [$sce:unsafe] Attempting to use an unsafe value in a safe context.
In that case, $sce service needs to be used like this:
$scope.user.errorText = $sce.trustAsHtml("Email is incorrect . <a href='#'>View Examples</a>");

After using $sce.trustAsHtml, ng-click not working

I am trying to print to the screen custom html using angular. I am using $sce.trustAsHtml in combination with ng-bind-html to accomplish this. The goal is not only to be able to print this custom html, but that it will retain directives such as ng-click and they will be usuable. Examples I have seen in articles such as follows are promising:
AngularJS render HTML within double curly brace notation
However in my implementation I find that although the html renders correctly including references to ng-click, the directive doesn't seem to work anymore when trying to click on the link I am using it on; here is some sample code:
$scope.htmlExpression = $sce.trustAsHtml("<a ng-click='test();'>Click Me</a>");
$scope.test = function() {
console.log('Hello World!');
}
<div>
<p ng-bind-html="htmlExpression"></p>
</div>
As everything renders fine and nothing appears lost in translation when analyzing the source; I am left feeling as if I have left something out. Any help is appreciated.
Use https://docs.angularjs.org/api/ngSanitize and bind the html. If this does not work, $digest to reboot the digest cycle.

Dynamically arranged html components the angular way [duplicate]

I'm making an in game UI using awesomium, at some points the game loads up and executes a chunk of javascript which is meant to create arbitrary new UI elements. e.g.
jQuery(document.body).append('<span class="game-status-alert">You Lose!</span>');
That works nicely, the problem comes when I want to create some slightly more advanced UI elements, specifically using angular. For example something like:
function ChatBoxControl($scope) { /* Stuff */ }
jQuery(document.body).append(
'<div ng-controller="ChatBoxControl"><div ng-repeat="line in chat"><span>{{line}}</span></div></div>'
);
Not surprisingly, this does not create a new angular view. It simply adds that html to the document and never binds to the ChatBoxControl.
How can I achieve what I'm trying to do here?
You should $compile dynamically added angular content.
Something like:
jQuery(document.body).append(
$compile(
'<div ng-controller="ChatBoxControl"><div ng-repeat="line in chat"><span>{{line}}</span></div></div>'
)(scope)
);
scope for any element you can get using something like:
var scope = angular.element('#dynamicContent').scope();
Also you should get $compile that can be injected in other controller.
See also: AngularJS + JQuery : How to get dynamic content working in angularjs
You might want to use ng-include combined with ng-repeat.
Here is an simple example: http://plunker.no.de/edit/IxB3wO?live=preview
<div ng-repeat="dom in domList" ng-include="dom"></div>
Parent $scope will keep the list of partials loaded into the view.
And ng-repeat + ng-include will iterate over and display partials according
to the list.
When it is the right timing, you can append the partial into the dom list. e.g.
$scope.domList.push("chatbox.html");
(BTW, putting DOM manipulation into controller is not the angular way.)

Angularjs animate ngClick + ngShow with custom directive (mySlide)

I'm trying to get the same ultimate functionality as ng-click + ng-show, except that I want the show to slide in instead of suddenly appear by toggling display: block/none;. I've got the jQuery animate I need, and I've set up the ng-click. I've got 2 problems, but the second might be a result of the first:
Problem 1
ng-click does not change the value of aside_users. I saw SO#12202067 which seems to be a similar situation, but I don't understand how/why their custom directive works and the native ng-click doesn't.
I see the scope: { … } after restrict: 'A',, but that appears to make $scope values available within the newly-created DOM element (my elements already exist and show up just fine, but no triggers/events are happening).
infobox.html
<aside
class="users"
ng-include src="'views/users.html'"
my-slide={"direction":"left","condition":"aside_users"}
></aside>
<i
class="icon icon-user"
ng-click="aside_users=!aside_users"
ng-init="aside_users=false"
></i>
The above code is a $compile'd template and elsewhere within the template I print out the value of the $scope parameter aside_users (prints false).
Problem 2
my-slide doesn't seem to be initiated/triggered (the logging of 'elm: ', elm doesn't appear in Chrome's console). I verified that directives.js is linked in my index.html page.
EDIT I remembered to link directives.js in index.html, but I forgot to add it to the resources array in app.js.
Plunkr
P.S. I'm not sure if <aside attr={object}> is strictly valid, but legitimate browsers seem to accept it in test cases (didn't bother to check IE). My alternate plan is to use 2 attributes: <foo my-slide="direction" my-condition="boolean"></foo>

Categories

Resources