Tom
Tom

Reputation: 1565

Angular compile in directive seems to go into infinite loop

I have a directive with dynamic text. I want to be able to have ng-click directives to call functions from the text. I understand the best way to do this is to compile the html into a template. But when I try to do this I get into an infinite loop:

angular.module('app')
  .directive('times', ['$compile', function ($compile) {
    return {
      restrict: 'E',
      link: function postLink(scope, element, attrs) {
        scope.selectDay = function() {
          console.log("Clicked on directive");
        }

        var content = element.html("<div><span ng-click='selectDay()'>Some test content</span></div>");
        var compiled = $compile(content);
        element.append(content);
        compiled(scope);        
      }
    };
  }]);

Upvotes: 3

Views: 4694

Answers (4)

Eyal
Eyal

Reputation: 532

You need to re-order your content creation and compilation. Create the content, then create the compile function, then compile and then append the compiled content. DEMO: http://jsfiddle.net/d2ayw9vz/

angular.module("app",[])
  .directive('times', ['$compile', function ($compile) {
    return {
      restrict: 'E',
      link: function postLink(scope, element, attrs) {
        scope.selectDay = function() {
          console.log("Clicked on directive");
        };

        var content = "<div><span ng-click='selectDay()'>Some test content</span></div>";
        var compiled = $compile(content);
        var linked =compiled(scope);    
        element.append(linked);



      }
    };
  }]);

Upvotes: 0

yisbug
yisbug

Reputation: 9

In a simple way, like this:

angular.module('app').directive('times', [
    '$compile',
    function($compile) {
        return {
            restrict: 'E',
            template: '<div><span ng-click="selectDay()">test</span></div>',
            link: function(scope, element, attrs) {
                return scope.selectDay = function() {
                    return console.log('Clicked on directive');
                };
            }
        };
    }
]);

Upvotes: 0

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

Your problem is with you were compiling wrong element after appended it to DOM, You should first compile the new element with scope and then append to the directive element

CODE

angular.module('app', [])
.directive('times', ['$compile', function($compile) {
  return {
    restrict: 'E',
    link: function postLink(scope, element, attrs) {
      scope.selectDay = function() {
        console.log("Clicked on directive");
      }

      var content = "<div><span ng-click='selectDay()'>Some test content</span></div>";
      var compiled = $compile(content);
      element.append(compiled(scope));
    }
  };
}]);

Plunkr

Upvotes: 2

Omri Aharon
Omri Aharon

Reputation: 17064

You need to change the way you are compiling. First give the element the content, and then compile its content with the scope:

element.html("<div><span ng-click='selectDay()'>Some test content</span></div>");
$compile(element.contents())(scope);

Fiddle

Upvotes: 2

Related Questions