Search code examples
angularjsangularjs-directiveangularjs-compile

Can Angular directive compile ng-click elements


I wrote a directive that will render subelements with ng-click directive on them, this is the code I have :

DIRECTIVE

angular.module('myApp')
  .directive('popover', [
    '$compile',
    function($compile) {
      return {
        scope: {
          items: "=",
        },
        link: function($scope, $element, $attrs){
          $.each($scope.items, function(key, value) {
            var item = '<a ng-click="'+value.ngClick+'">'+value.name+'</a>';
            $element.append($compile(item)($scope));
          });
        }
      }
    }
  ]
);

TEMPLATE

<div popover items="myItems"></div>

CONTROLLER

angular.module('myApp')
  .controller('MyCtrl', [
    '$scope',
    function ($scope) {

      $scope.myItems = [
        {name: 'Do this', ngClick: 'doThis()' },
        {name: 'Do that', ngClick: 'doThat()' },
      ];

      $scope.doThis = function() { console.log('this is done') };
      $scope.doThat = function() { console.log('that is done') };

    }
  ]
);

The rendring works fine, I get a list of A element with right attribute ng-click on it, but the functions doThis() and doThat() are never triggered

I suppose the problem to be near the $compile command, but I already used this command in other context and it seemed to work fine this way. Also, in Chrome dev toolbar, I see no event related to ng-click directive for the elements.

Any idea ? Thanks


Solution

  • Your directive has an isolated scope so doThis and doThat are not is the directive's scope. Either you remove the isolated scope, or you could pass your functions like this:

    app.controller('MainCtrl', function($scope) {
      $scope.myItems = [
            {name: 'Do this', ngClick: doThis },
            {name: 'Do that', ngClick: doThat },
          ];
    
          function doThis() { console.log('this is done') };
          function doThat() { console.log('that is done') };
    });
    
    app
      .directive('popover', function($compile) {
          return {
            scope: {
              items: "=",
            },
            link: function($scope, $element, $attrs){
              $scope.clickFunctions = {};
              $.each($scope.items, function(key, value) {
                $scope.clickFunctions[value.name] = value.ngClick
                var item = '<a ng-click="clickFunctions[\''+value.name+'\']()">'+value.name+'</a>';
                $element.append($compile(item)($scope));
              });
            }
          }
        }
    );
    

    See this plunker for demo.