Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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

share|improve this question
    
Yes, that is not exactly how angular wants to work. If you want to add html dynamically, look into the $complie service. –  Davin Tryon Nov 1 '13 at 11:53
2  
why do not you use ngScript to create the about template and then use an ng-include,ng-src to add it –  Vinod Louis Nov 1 '13 at 11:55

4 Answers 4

up vote 2 down vote accepted

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:

JSON Response

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

Output =

<div bind-html-compile="letterTemplate.content"> 
   <div> Dear John, </div>
</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);
                });
            }
        };
    }]);
}());
share|improve this answer

One way is use a directive for purpose of inserting custom templates that include angular expresssions

<div id="unicTab" unic-tab-content></div>
app.directive("unicTabContent",function(){
   return {
      restrict:"A",
      template:'{{unicTabContent}}'
   }
})
share|improve this answer
    
I like this idea, and it does include the code, but it is still not compiled. –  karlito139 Nov 1 '13 at 13:22
1  
works fine here as is plnkr.co/edit/sUOxHBUYIdQlAiM3Dy0V?p=preview Perhaps you have some nested directives or something else causing it not to work –  charlietfl Nov 1 '13 at 16:51
1  
But I'd like it to compile the code in the variable that you called test. For exemple plunker display the <div> and </div>, which is not what I'd like. –  karlito139 Nov 1 '13 at 17:20
1  
OK..can do it with link callback of directive Plunker –  charlietfl Nov 1 '13 at 17:28
1  
Indeed it compile html, but not the angular statements. In Plunker when the test variable is directly injected the ng-click method is connected, but when injected using the directive it isn't. –  karlito139 Nov 1 '13 at 17:43

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.

share|improve this answer
2  
I like this solution, but it would have been better if we could see a sample where the HTML is coming from somewhere else (remote JSON for example and thus not hard coded in the project). –  Wouter May 4 '14 at 7:46

I was trying to do the same thing and came across this module.

http://ngmodules.org/modules/ng-html-compile

I just included it and then I was able to use "ng-html-compile" instead of "ng-bind-html"

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.