3

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

Vincent Wasteels
  • 1,568
  • 2
  • 14
  • 21
  • You can do the same as @etiennecrb or change your `$scope.myItems` into `$scope.myItems = [{name: 'Do this', ngClick: '$parent.doThis()' }, {name: 'Do that', ngClick: '$parent.doThat()' }];`, but i will not recommend this way be cause it is an ugly hack. [Fiddle](https://jsfiddle.net/themyth92/f6r8nv5o) – themyth92 Apr 29 '16 at 10:56

1 Answers1

4

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.

etiennecrb
  • 597
  • 2
  • 10