3

I'm generating SVG nodes in my app. Now I'm struggling to add a compatible Angularjs event to a node.

The idea is simple. I'm creating a new text svg node and when the user click on this text element I want to open a specific menu.

But as expected the "ng-click" event is not recognized. I tried to use scope.$apply(), but did not work. So I was wondering if the right thing to do is to use the $compile. But, even so, how to use the $compile in the following case.

This is my view, when the user clicks creates a new node.

    <div ng-click="addElementToSection(data)">
...
    </div>

this is my function creating the new node and where I specify the click event of the text node. (How to use the $compile here? Would be the solution?)

scope.addElementToSection = function(dataElement, varDefined){
...
            var t = s.text(latestPositionX, yTop, dataElement.value);

            t.attr({
                class: 'svg-text',
                'ng-click': 'openRightMenu(menu)'
            });

            s.select('g').append(t);
...

}

This is the final result, but as mentioned the ng-click does not trigger any event.

<text x="20" y="875.2192993164062" ng-click="openRightMenu(menu)" class="svg-text">Test1</text>

How to deal with this kind of case?

UPDATED:

I have a specific directive to load a SVG file with snapsvg.

<li
        ng-repeat="section in sections | filter:{visible: true}"
        svg-loader="{{section.svg}}">
</li>

Here the snippet of code to load the SVG:

                var tux = Snap.load(svg, function ( loadedFragment ) {
                    snap.append( loadedFragment );
                });

This is an example of SVG that Im manipulating. This SVG is loaded from a SVG file created in any SVG tool.

<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="1000" height="200" id="svg2">

  <defs id="defs4"></defs>

  <metadata id="metadata7">
    <rdf:rdf>
      <cc:work rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"></dc:type>
        <dc:title></dc:title>
      </cc:work>
    </rdf:rdf>
  </metadata>

  <g transform="translate(0,-852.36218)" id="layer1">

    <rect width="1000" height="200" x="-1000" y="855.2193" transform="scale(-1,1)" id="rect2985" style="fill:#ffb380;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"></rect>

    <path d="M 101,77.000002 77.597533,65.593187 54.933655,78.404885 58.550419,52.622916 39.362247,35.027319 64.999999,30.499999 75.804935,6.813625 88.033172,29.797557 113.89916,32.75417 95.818876,51.48634 z" transform="translate(0,852.36218)" id="path2995" style="fill:#ffffff"></path>

    <path d="M 728,35 714.62841,36.415519 708.21393,48.233193 702.73564,35.953477 689.51418,33.504801 699.5,24.5 l -1.75683,-13.331039 11.64987,6.714443 12.13568,-5.790359 -2.78581,13.154555 z" transform="translate(0,852.36218)" id="path2997" style="fill:#ffffff"></path>

    <path d="M 259,51 230.45494,57.682466 219.77717,84.9856 204.60085,59.902628 175.33442,58.184596 194.5,36 187.09012,7.6350643 214.11142,19.007202 238.7983,3.1947398 236.33279,32.407703 z" transform="translate(0,852.36218)" id="path2999" style="fill:#ffffff"></path>

    <path d="m 547,158 -46.79723,-24.29851 -46.54659,24.77525 8.64812,-52.01546 -37.94635,-36.61246 52.14205,-7.848817 23.09446,-47.402997 23.57745,47.164626 52.21951,7.315799 -37.5704,36.998159 z" transform="translate(0,852.36218)" id="path3001" style="fill:#ffffff"></path>

    <path d="m 120,138 a 28,26 0 1 1 -56,0 28,26 0 1 1 56,0 z" transform="translate(0,852.36218)" id="path3005" style="fill:#ffffff"></path>

    <path d="m 824,92 a 88,87 0 1 1 -176,0 88,87 0 1 1 176,0 z" transform="translate(0,852.36218)" id="path3007" style="fill:#ffffff"></path>

    <rect width="179" height="43" x="185" y="118" transform="translate(0,852.36218)" id="_DRAG_rect3009" style="fill:#ffffff"></rect>

    <text x="20" y="875.2192993164062" ng-click="alert(11)" class="svg-text">Test1
    </text>

</g>

  <desc>Created with Snap</desc>

</svg>
Thiago C. S Ventura
  • 2,448
  • 1
  • 29
  • 43
  • Is it that any event isn't triggered, or just the openRightMenu doesn't work? Ie if you put an alert in there instead, does it fire ? – Ian Nov 30 '14 at 13:20
  • even a simple alert() does not work. – Thiago C. S Ventura Nov 30 '14 at 13:26
  • 2
    I don't think angular can "see" new ng-clicks when added like that. I believe you should use a more angular way, making a ng-repeat on your HTML iterating through a collection and your add function simply push a new item into that collection. – Fedaykin Nov 30 '14 at 13:30
  • I know this is a DOM manipulation, that's why Im doing in a directive. And how to follow that approach with a whole SVG document? (I'll update ith more infos) – Thiago C. S Ventura Nov 30 '14 at 13:47
  • great, if you can provide a plunker it would be even better – Fedaykin Nov 30 '14 at 13:55
  • @Fedaykin After reading this link: http://stackoverflow.com/questions/19568226/angular-js-rendering-svg-templates-in-directives . I've got your point. – Thiago C. S Ventura Dec 01 '14 at 10:10
  • But I'm still think how I can create a repeat based on the nodes coming from the SVG file. I could use snapsvg to get all nodes for a directive called svg-text for example. But how to attach it to a repeat? – Thiago C. S Ventura Dec 01 '14 at 10:13

1 Answers1

1

Ok. This tutorial here gave me the main idea.

Basically this part solved my problem:

angular.module('SvgMapApp').directive('svgMap', ['$compile', function ($compile) {
    return {
        restrict: 'A',
        templateUrl: 'img/Blank_US_Map.svg',
        link: function (scope, element, attrs) {
            var regions = element[0].querySelectorAll('.state');
            angular.forEach(regions, function (path, key) {
                var regionElement = angular.element(path);
                regionElement.attr("region", "");
                $compile(regionElement)(scope);
            })
        }
    }
}]);

angular.module('SvgMapApp').directive('region', ['$compile', function ($compile) {
    return {
        restrict: 'A',
        scope: true,
        link: function (scope, element, attrs) {
            scope.elementId = element.attr("id");
            scope.regionClick = function () {
                alert(scope.elementId);
            };
            element.attr("ng-click", "regionClick()");
            element.removeAttr("region");
            $compile(element)(scope);
        }
    }
}]);
Thiago C. S Ventura
  • 2,448
  • 1
  • 29
  • 43