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

Asked

Viewed 281 times

0

I made a simpler example for my problem:

Inside my controller is 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>

Because the method doesn’t work?

Obs: When I don’t put the trustAsHtml, he’s returning me as object.

1 answer

1


The problem

I believe that in your case the approach is wrong. It seems you are trying to define the content of a button created dynamically within a div.

The problem of doing this with ng-bind-html is that you would need to have html in string format. In the case of $compile, when you build 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 the 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>

Note that the example works exactly as expected. o myAction is called correctly and the element is created within the div, with the small modification relative to the id.

About the ng-bind-html

The problem of trying to inject this button with ng-bind-html is that the ng-bind-html only accepts HTML expressions in the format of string. 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 estate outerHtml returns the contents of the element itself as an HTML string. The problem is that you would lose the reference to the myAction and the function would not be executed, since the idea of the $compile is to prepare the html that will be inserted dynamically to enter the processing cycle of Angularjs.

Tip

I also add the information that, in your case, it might be more advantageous to work with directives to create more dynamic functionalities.

The directives help a lot in the reuse of code, avoiding useless repetitions too.

Link to the directive documentation: https://docs.angularjs.org/guide/directive

Browser other questions tagged

You are not signed in. Login or sign up in order to post.