How to Make Ng-Bind-Html Compile Angularjs Code

ng-bind-html vs bind-html-compile?

bind-html-compile is not a standard Angular directive, it comes with the module https://github.com/incuna/angular-bind-html-compile and it is used to compile binded data.To make it simple, it is equivalent to write html in your source code: it will be re-evaluated and if other directives are found, they will work as expected.

ng-bind-html is a standard directive (bundled with Angular itself) and just output html strings without compiling it.

for example, if you controller has a variable with plain html, like in:

$scope.dataToDisplay = '<h1><strong>Title</strong></h1>';

Then you can go with ng-bind-html.

If you need to inject variables that contain html with other directives, such as:

$scope.dataToDisplay = '<h1 ng-show="showIfOtherVariable"><strong>Title</strong></h1>';

then you need to aforementioned module.

How to make ng-bind-html compile angularjs code

This solution doesn't use hardcoded templates, and you can compile Angular expressions embedded within an API response.


Step 1.
Install this directive: https://github.com/incuna/angular-bind-html-compile

Step 2. Include the directive in the module.

angular.module("app", ["angular-bind-html-compile"])

Step 3. Use the directive in the template:

<div bind-html-compile="letterTemplate.content"></div>

Result:

Controller Object

 $scope.letter = { user: { name: "John"}}

JSON Response

{ "letterTemplate":[
{ content: "<span>Dear {{letter.user.name}},</span>" }
]}

HTML Output =

<div bind-html-compile="letterTemplate.content"> 
<span>Dear John,</span>
</div>

For reference sake, here's the relevant directive:

(function () {
'use strict';

var module = angular.module('angular-bind-html-compile', []);

module.directive('bindHtmlCompile', ['$compile', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch(function () {
return scope.$eval(attrs.bindHtmlCompile);
}, function (value) {
element.html(value);
$compile(element.contents())(scope);
});
}
};
}]);
}());

AngularJS ng-bind-html and components

Did you do the following on your scope variable which holds the html code? This is a common mistake.

$scope.trustAsHtml('<div>....')

But as mentioned before, without your code it is hard to figure out the problem.

compile ng-bind-html inside ng-repeat

Use the transclude function furnished as the second argument of the function created by the $compile service:

app.directive("compileBindExpn", function($compile) {
return function linkFn(scope, elem, attrs) {
scope.$watch("::"+attrs.compileBindExpn, function (html) {
var expnLinker = $compile(html);
expnLinker(scope, function transclude(clone) {
elem.empty();
elem.append(clone);
})
});
};
});

The above directive evaluates the compile-bind-expn attribute as an AngularJS expression. It then uses the $compile service to bind the evaluated HTML to the element. Any existing content will be removed.

Usage:

<div class="buy-button-container" compile-bind-expn="buttonCode">
<p>This Node disappears when expression binds</p>
</div>

Note that the directive uses a one-time binding in the $watch to avoid memory leaks.

The DEMO on JSFiddle

I want to display html page which has angularjs code ($compile/ng-bind-html not working)

I tried with iframe,, and it works,,, :)
Either we have to save the response in an HTML file and use it like this,,,,,,,

<iframe src="htmlResponse.html"> </iframe>

Or we can directly assign the rootscope variable to it.

<iframe width="100%" height="500px" ng-attr-srcdoc="{{htmlResponse}}"></iframe>

AngularJS 1.5 bind and compile html to modal

I found this fiddle: http://jsfiddle.net/NWZZE/6/

From this SO post: angular ng-bind-html and directive within it

Also of note is the non-standard directive: https://github.com/incuna/angular-bind-html-compile/blob/master/angular-bind-html-compile.js

After reading up more and honing my search, I implemented this directive in my module and used it almost exactly like the Fiddle. Works perfectly...just remember to remove the call to $sce.trustAsHtml.

Not able to get ng-bind-html to work

When you use ng-bind-html, AngularJS sometimes consider some contents as unsafe (as your case), so you need to use the $sce service in order to "mark" this content as safe (to be used) like this:

$sce.trustAsHtml("CLINICAL & SOCIAL"); (See demo below)

From $sanitize

The input is sanitized by parsing the HTML into tokens. All safe
tokens (from a whitelist) are then serialized back to properly escaped
html string. This means that no unsafe input can make it into the
returned string
.

In this case the "unsafe" part is &

angular.module('app', []).controller('ctrl', ctrl);
function ctrl($scope, $sce) {$scope.Specialty = $sce.trustAsHtml("CLINICAL & SOCIAL");}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-sanitize.js"></script>
<div ng-app="app" ng-controller="ctrl">
Specialty: <span ng-bind-html="Specialty"></span>
</div>

Using ng-bind-html and $sce.trustAsHtml create a string with ng-model binding

HTML :

Add a directive: compile-template

<div ng-bind-html="htmlString" compile-template></div>

JS :

angular.module('ngApp', ['ngSanitize'])
.controller('controller1', ['$scope','$sce', function($scope, $sce) {
var str = "<input type='text' ng-model='" + $scope.selectedData.code + "' class='form-control' />";
$scope.htmlString = $sce.trustAsHtml(str);
}])
.directive('compileTemplate', function($compile, $parse){
return {
link: function(scope, element, attr){
var parsed = $parse(attr.ngBindHtml);
function getStringValue() {
return (parsed(scope) || '').toString();
}

// Recompile if the template changes
scope.$watch(getStringValue, function() {
$compile(element, null, -9999)(scope); // The -9999 makes it skip directives so that we do not recompile ourselves
});
}
}
});

AngularJS directive in ng-bind-html

You need to import the ngSanitize module and use the $sce service. It should look something like this:

// Remember the following comes from angular-sanitize.js found on the angular website and
// also must be included in the web app.
angular.module('myApp', ['ngSanitize']);
angular.module('myApp')
.controller('MyCtrl', function($scope, $sce) {
//... other controller code
$scope.renderHtml = function(html) {
return $sce.trustAsHtml(html);
};
});

In short, the $sce service will mark the html as trusted. You can find documentation here

EDIT: I realize I may have not answered the question. It seems that you're asking about binding scope variables to the directive that is rendered within your directive? In order to get elements to compile properly, you're going to have to use the $compile service and change your logic up a bit. First, the template:

<p class="place-directive-here"></p>

Then the directive:

angular.module('myApp')
.directive('myDirective', function($compile) {
return {
scope: {
inlineWidget: '='
},
template: '<p class="place-directive-here"></p>',
link: function(scope, elem, attrs) {
var placement = elem.find('.place-directive-here');
scope.$watch('inlineWidget', function(widget){
if(!widget){
return;
}
// Compile the html against the scope. This will bind the dom to your
// current scope
var newElement = $compile(widget.blah)(scope);
// Place in the view
placement.html(newElement);
});
}
};
});

You can find the compile documentation here. Hopefully this is a more comprehensive answer to what you're looking for.

EDIT 2: For clarification, the directive should look like this on the page:

<div my-directive inline-widget="someInlineWidget"></div>

The place-directive-here class is just a handle for the directive to find your <p> tag and render inside of it. However, if angular is not concerned with the html that is rendered inside of my-directive, the first solution that I provided should work just fine and the template property of my-directive should be:

template: '<p ng-bind-html="renderHtml(inlineWidget.blah)"></p>'


Related Topics



Leave a reply



Submit