1

Using the angular directive Max created on this post for easily importing SVGs, I've imported a handful of SVGs on my page. I now want to add a click event to an SVG, except the directive doesn't transfer the click method to the imported SVG. If I inspect the SVG in my browser I see that it is indeed missing the ng-click.

HTML

<svg-image class="svg foo" src="img/foo.svg" ng-click="bar()"></svg-image>

JS

$scope.bar = function() {
  console.log("click");
};

If I move ng-click="bar()" to another element on my page it works just fine. I've also tried moving ng-click="bar()" to the svg file itself which didn't work, and I've tried doing what was suggested in this post which didn't work either.

plunker as requested: https://plnkr.co/edit/eqOZJO5Ar8oOmXCjg3Vs

Community
  • 1
  • 1
Joseph Webber
  • 2,010
  • 1
  • 19
  • 38

2 Answers2

1

One of possible solutions is to compile your new element and call resulting template function, passing in scope:

.directive('svgImage', ['$http', '$compile', function($http, $compile) {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      var imgURL = element.attr('src');
      // if you want to use ng-include, then
      // instead of the above line write the bellow:
      // var imgURL = element.attr('ng-include');
      var request = $http.get(
        imgURL,
        {'Content-Type': 'application/xml'}
      );

      scope.manipulateImgNode = function(data, elem){
        var $svg = angular.element(data)[4];
        var imgClass = elem.attr('class');
        if(typeof(imgClass) !== 'undefined') {
          var classes = imgClass.split(' ');
          for(var i = 0; i < classes.length; ++i){
            $svg.classList.add(classes[i]);
          }
        }
        $svg.removeAttribute('xmlns:a');
        angular.element($svg).attr("ng-click", attrs.ngClick);
        return $compile($svg)(scope);
      };

      request.success(function(data){
        element.replaceWith(scope.manipulateImgNode(data, element));
      });
    }
  };
}]);

Plunker

Yuriy Rozhovetskiy
  • 22,270
  • 4
  • 37
  • 68
0

Try this

var jimApp = angular.module("mainApp",  []);
jimApp.controller('mainCtrl', function($scope){
    $scope.bar = function() {
        console.log("click");
    };
});
jimApp.directive('svgImage', function() {
        return {
            restrict: 'E',
            replace: true,
            scope: {
                onClick: '&'
            },
            template: '<div ng-click="bar();">Hai</div>',
            link: function(scope, element, attrs, fn) {
            scope.bar = function(){
               scope.onClick()();
            }
            }
        };
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="mainApp" ng-controller="mainCtrl">
asas
  <svg-image on-click="bar"></svg-image>
</div>
byteC0de
  • 5,153
  • 5
  • 33
  • 66