Compiling dynamic HTML strings from database Compiling dynamic HTML strings from database angularjs angularjs

Compiling dynamic HTML strings from database


ng-bind-html-unsafe only renders the content as HTML. It doesn't bind Angular scope to the resulted DOM. You have to use $compile service for that purpose. I created this plunker to demonstrate how to use $compile to create a directive rendering dynamic HTML entered by users and binding to the controller's scope. The source is posted below.

demo.html

<!DOCTYPE html><html ng-app="app">  <head>    <script data-require="angular.js@1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>    <script src="script.js"></script>  </head>  <body>    <h1>Compile dynamic HTML</h1>    <div ng-controller="MyController">      <textarea ng-model="html"></textarea>      <div dynamic="html"></div>    </div>  </body></html>

script.js

var app = angular.module('app', []);app.directive('dynamic', function ($compile) {  return {    restrict: 'A',    replace: true,    link: function (scope, ele, attrs) {      scope.$watch(attrs.dynamic, function(html) {        ele.html(html);        $compile(ele.contents())(scope);      });    }  };});function MyController($scope) {  $scope.click = function(arg) {    alert('Clicked ' + arg);  }  $scope.html = '<a ng-click="click(1)" href="#">Click me</a>';}


In angular 1.2.10 the line scope.$watch(attrs.dynamic, function(html) { was returning an invalid character error because it was trying to watch the value of attrs.dynamic which was html text.

I fixed that by fetching the attribute from the scope property

 scope: { dynamic: '=dynamic'}, 

My example

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


Found in a google discussion group. Works for me.

var $injector = angular.injector(['ng', 'myApp']);$injector.invoke(function($rootScope, $compile) {  $compile(element)($rootScope);});