How do I put a function inside ng-bind-html?

0

I gave a simpler example to my problem:

Inside my controller looks like this:

$rootScope.myAction = function(){
    alert('Olá mundo!');
}

$scope.setAction = function() {

 var comp = $compile('<button ng-click="myAction()">Teste</button>')($scope);
 return $sce.trustAsHtml(comp);
};

$rootScope.result = $scope.setAction();

And in HTML like this:

<div ng-bind-html="result"></div>

Why does not the method work?

Note: When I do not put trustAsHtml , it is returning me as an object.

    
asked by anonymous 19.09.2018 / 18:04

1 answer

1

The problem

I believe that in your case the approach is wrong. It looks like you're trying to set the contents of a button created dynamically within a div .

The problem with doing this with ng-bind-html is that you would need to have the html in a string format. In the case of $compile , when you construct the element with it, it will return an object, equivalent to the call of angular.element() .

That's why in your case it's not working.

The Solution

I believe the best approach is to use angular.element to add the element, which you "compiled" to Angular, in your div .

I did so:

angular.module('app', [])
.controller("AppController", function($scope, $compile, $sce) {
  
  $scope.myAction = function () {
    
    alert('Olá');
  };
  
  $scope.setAction = function() {
    
    var comp = $compile('<button ng-click="myAction()">Teste</button>')($scope);
    
    angular.element(document.querySelector('#content')).append(comp);
  };
  
  $scope.setAction();
  
});
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="app">
  
  <div ng-controller="AppController">
    <div id="content"></div>
  </div>  
</div>

See that the example works exactly as expected. the myAction is called correctly and the element is created inside the div, with the small change to id .

About ng-bind-html

The problem with trying to inject this button with ng-bind-html is that ng-bind-html only accepts HTML expressions in string format. It will not work with the object returned by angular.element .

With your code, you would have a way to get the html returned by $compile , as follows:

 var comp = $compile('<button ng-click="myAction()">Teste</button>')($scope);

return $sce.trustAsHtml(comp[0].outerHTML);

The outerHtml property returns the contents of the element itself as an HTML string. The problem is that you would lose the reference to myAction and the function would not be executed, since the idea of $compile is to prepare the html that will be inserted dynamically to enter the processing cycle of AngularJS.

Tip

I further add that in your case, it might be more advantageous to work with policies to create more dynamic features.

Directives help a lot in reusing code, avoiding unnecessary repetitions as well.

Policy documentation link: link

    
20.09.2018 / 18:35