Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make ng-bind-html compile angularjs code

I am working with angularjs 1.2.0-rc.3. I'd like to include html code into a template dynamically. For that I use in the controller :

html = "<div>hello</div>";
$scope.unicTabContent = $sce.trustAsHtml(html);

In the template I got :

<div id="unicTab" ng-bind-html="unicTabContent"></div>

It works fine for regular html code. But when I try to put angular template it is not interpreted, it is just included in the page. For example I'd like to include :

<div ng-controller="formCtrl">
    <div ng-repeat="item in content" ng-init="init()">
    </div>
</div>

Thanks a lot

like image 577
Clement Roblot Avatar asked Nov 01 '13 11:11

Clement Roblot


People also ask

What is Ng-bind-HTML in AngularJS?

The ng-bind-html directive is a secure way of binding content to an HTML element. When you are letting AngularJS write HTML in your application, you should check the HTML for dangerous code. By including the "angular-sanitize.

Does ng-bind bind the application data to HTML tags in AngularJS?

ng-bind directive binds the AngularJS Application data to HTML tags. ng-bind updates the model created by ng-model directive to be displayed in the html tag whenever user input something in the control or updates the html control's data when model data is updated by controller.

How AngularJS is compiled?

Compiler is an AngularJS service which traverses the DOM looking for attributes. The compilation process happens in two phases. Compile: traverse the DOM and collect all of the directives. The result is a linking function.

How do I bind HTML in angular 6?

Data Binding is available right from AngularJS, Angular 2,4 and is now available in Angular 6 as well. We use curly braces for data binding - {{}}; this process is called interpolation. We have already seen in our previous examples how we declared the value to the variable title and the same is printed in the browser.


3 Answers

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);
                });
            }
        };
    }]);
}());
like image 158
Ryan.lay Avatar answered Oct 21 '22 02:10

Ryan.lay


This is what I've made, no idea if it's the angular wayTM, but it works and is super simple;

.directive('dynamic', function($compile) {
    return {
        restrict: 'A',
        replace: true,
        link: function (scope, element, attrs) {
            scope.$watch(attrs.dynamic, function(html) {
                $compile(element.html(html).contents())(scope);
            });
        }
    };
});

So;

<div id="unicTab" dynamic="unicTabContent"></div>

Edit: I found the angular way, and it's super simple.

$templateCache.put('unicTabContent', $sce.trustAsHtml(html));
<div id="unicTab" ng-include="'unicTabContent'"></div>

Don't need to make your own directives or anything. But it's a bind-once sort of deal, it wont see changes made to your html like the custom directive does.

like image 22
Hashbrown Avatar answered Oct 21 '22 00:10

Hashbrown


As Vinod Louis says in his comment, the best way to do that was to use templates. I had to define a template outside of the regular code, for example I added that code inside of my index.html :

<script type="text/ng-template" id="unic_tab_template.html">
    <div ng-switch on="page">
        <div ng-switch-when="home"><p>{{home}}</p></div>
        <div ng-switch-when="form">
            <div ng-controller="formCtrl">
                <div ng-repeat="item in content">{{item.name}}:{{item.value}}</div>
            </div>
        </div>
        <div ng-switch-default>an error accured</div>
    </div>
</script>

This template is conditional, so depending on the value of $scope.page, it switches between the 3 templates (the third being an error handler). To use it I had :

<div id="unicTab" ng-controller="unicTabCtrl">
    <div ng-include="'unic_tab_template.html'"></div>
</div>

That way my page changes depending on the $scope inside of my unicTabCtrl controller.

To conclude the idea of inserting angularsjs template seams to be difficult to realize ($compile seams to be the solution, but I wasn't able to make it work). But instead you may use conditional templating.

like image 2
Clement Roblot Avatar answered Oct 21 '22 01:10

Clement Roblot