23
votes

I've included a Plunker here: http://plnkr.co/edit/4vqV8toHo0vNjtfICtzI?p=preview

I'm trying to add a button to the DOM and when clicked should execute the function bound to it. In this case it should alert "testing". Here is the code.

controller

app.controller('MainCtrl', function($scope, $sce) {
        $scope.trustedHtml = $sce.trustAsHtml('<button ng-click="testAlert()">Submit</button>');  

        $scope.testAlert = function () {
            alert('testing')
        };
});

HTML

<body ng-controller="MainCtrl">
    <div ng-bind-html="trustedHtml"></div>
</body>
2

2 Answers

26
votes

$sce.trustAsHtml and ng-bind-html are not meant to build HTML with directives. This technique will not work.

This is because angular works by first compiling and then linking. See the conceptual overview for a good explaination.

In short, by the time you link the HTML defined in your trustAsHtml, it is too late for angular to compile (and therefore understand) the ng-click directive.

In order to dynamically add HTML, you should be looking at the $compile service (and/or directives). Docs are here.

11
votes

For Angular 1.6.1, I found a solution that worked for me.

template:

<div ng-bind-html="trustAsHtml(content);" init-bind> </div>

In controller:

    $scope.trustAsHtml = function(string) {
        return $sce.trustAsHtml(string);
    };

Directive:

.directive('initBind', function($compile) {
return {
        restrict: 'A',
        link : function (scope, element, attr) {
            attr.$observe('ngBindHtml',function(){
                if(attr.ngBindHtml){
                     $compile(element[0].children)(scope);
                }
            })
        }
    };
})