Search code examples
javascripthtmlangularjsangularjs-directiveng-bind-html

ng-bind-html and ng-controller


I'm injecting insecure html into some <div>, like this:

<div class="category-wrapper" ng-bind-html="content"></div>

this html has angularjs "code" ($scope.content is loaded with something like this):

<script type='text/javascript' src='giveus.js'></script>
<div class="giveus-wrapper" ng-controller="GiveUsController">{{variable1}}</div>

Note that this snippet has ng-controller. GiveUsController is lazy loaded at the same time that the embedded html (not in head). There is no error declaring this controller because It has been already tested.

My controller is as easy as:

angular.module("tf").controller('GiveUsController', function ($scope, $http)    
{
     console.debug("GiveUsController loaded");
     $scope.variable1 = "hi!";
}

there is no console debug nor variable1 assignment

It looks like there is no controller binding to that <div>.

I don't know how I can inject html with angular controller and make it work...

Any idea?


Solution

  • You could do what you are wanting with a bit of manual html compilation. Here is an approach that is essentially a directive wrapper for the $compile service. Observe the following example and usage...

     <div class="category-wrapper" ng-html="content"></div>
    

    .controller('ctrl', function($scope) {
        $scope.content = '<div class="giveus-wrapper" ng-controller="GiveUsController">{{variable1}}</div>'
    })
    .controller('GiveUsController', function($scope) {
    
        console.log('hello from GiveUsController')
        $scope.variable1 = 'I am variable 1'
    })
    .directive('ngHtml', ['$compile', function ($compile) {
        return function (scope, elem, attrs) {
            if (attrs.ngHtml) {
                elem.html(scope.$eval(attrs.ngHtml));
                $compile(elem.contents())(scope);
            }
            scope.$watch(attrs.ngHtml, function (newValue, oldValue) {
                if (newValue && newValue !== oldValue) {
                    elem.html(newValue);
                    $compile(elem.contents())(scope);
                }
            });
        };
    }]);
    

    JSFiddle Link - demo