How to determine the mouse event target model in AngularJS

I draw several elements in svg (using ng-switch) and handle mouse events on them. The controller looks like this (there are many types of elements and more mouse events to handle):

app.controller('MainCtrl', function($scope) {
  $scope.elements = [
    { "type": "circle", "x" : 100, "y" : 200 },
    { "type" : "rect", "x" : 50, "y" : 20 }
    ];

  $scope.mousedown = function(element, $event) {
    $scope.msg = element.type;  
  };
});

Inside the mouse event handler, I need a mouse object model. My current solution is to add ng-mousedown="mousedown(element, $event)"svg to each element, which annoys a growing number of element types.

    <g ng-switch="p.type">
      <g ng-switch-when="circle">
        <circle ng-mousedown="mousedown(p, $event)"></circle>
      </g>
      <g ng-switch-when="rect">
        <rect ng-mousedown="mousedown(p, $event)"></rect>
      </g>
    </g>

Is there a way to add ng-mousedownsvg only to the root element and get the model of the clicked element from the properties $event( $event.targetor $event.srcElementgive me the svg element with a click, how to get the model from this?).

Full example: http://plnkr.co/edit/nfgVSBBaeJ9EFKNjYEJn

+4
2

element.scope() , . , " ", , (. ).

, ng-repeat :

angular.module("app", [])
	.controller('MainController', MainController);

function MainController() {
	var vm = this;
	vm.elements = [
    { "type": "circle", "x" : 100, "y" : 100 },
    { "type" : "rect", "x" : 50, "y" : 20 }];

  vm.mousedown = function(element, $event) {
    vm.msg = element.type;  
  };
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MainController as view">

<svg xmlns="http://www.w3.org/2000/svg" width="300" height="120">
  <g ng-repeat="p in view.elements" ng-switch="p.type" 
     ng-mousedown="view.mousedown(p, $event)">

      <circle ng-switch-when="circle" 
              ng-attr-cx="{{p.x}}" ng-attr-cy="{{p.y}}" fill="red" r="20">
      </circle>
      <rect ng-switch-when="rect" 
            ng-attr-x="{{p.x}}" ng-attr-y="{{p.y}}" width="50" height="50" fill="blue" >
      </rect>

  </g>
</svg>
<p>
{{view.msg}}
</p>    
</div>
Hide result

eventSource eventHandler. eventHandler . eventSource " " .

angular.module("app", [])
  .controller('MainController', MainController)
  .directive('eventSource', eventSource)
  .directive('eventHandler', eventHandler);

function MainController() {
	var vm = this;
	vm.elements = [
    { "type": "circle", "x" : 100, "y" : 80 },
    { "type" : "rect", "x" : 50, "y" : 20 }
    ];
  vm.rect = { "type" : "special", "x" : 0, "y" : 40 };

  vm.handle = function(element, $event) {
    vm.msg = $event.type + ': ' + element.type;  
  };
}

function eventSource($parse) {
  return {
    restrict: 'A',
    require: '^eventHandler',
    link: function (scope, elem, attr, controller) {
      var sourceAttr = attr['eventSource'];
      var source = $parse(sourceAttr)(scope);
      controller.register(elem, source);
      scope.$on('$destroy', function () {
        controller.unregister(elem);
      });
    }
  };  
}

function eventHandler() {
  return {
    restrict: 'A',
    scope: {
      eventHandler: '&'
    },
    controller: function () {
      var vm = this;
      vm.sources = [];

      this.register = function (element, source) {
        vm.sources.push({element : element, source: source});
      }

      this.unregister = function (element) {
        var i = 0;
        for(var e = vm.sources.length; i < e; ++i) {
          if (vm.sources[i].element === element)
            break;
        }
        vm.sources.splice(i, 1);
      }
    },
    link: function (scope, elem, attr, controller) {

      elem.on('mousedown mouseup', function ($event) {

        var target = $event.target;
        while (target && !target.hasAttribute('event-source'))
          target = target.parentNode;
        
        for(var i = 0, e = controller.sources.length; i < e; ++i) {
          if (controller.sources[i].element[0] === target) {
              scope.eventHandler({element : controller.sources[i].source, $event : $event});
          }            
        }
        scope.$apply();
      });  
    }
  };
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="MainController as view">

<svg xmlns="http://www.w3.org/2000/svg" width="300" height="120" 
     event-handler="view.handle(element, $event)">
  
  <g ng-repeat="p in view.elements" ng-switch="p.type" 
     event-source="p">
      <circle ng-switch-when="circle" 
              ng-attr-cx="{{p.x}}" ng-attr-cy="{{p.y}}" fill="red" r="20">
      </circle>
      <rect ng-switch-when="rect" 
            ng-attr-x="{{p.x}}" ng-attr-y="{{p.y}}" width="50" height="50" fill="blue" >
      </rect>
  </g>
  <rect ng-attr-x="{{view.rect.x}}" ng-attr-y="{{view.rect.y}}" width="80" height="50" fill="green"
        event-source="view.rect">
  </rect>
</svg>
<p>
{{view.msg}}
</p>    
</div>
Hide result
+2

, angular.element(...).scope().p :

:

<svg xmlns="http://www.w3.org/2000/svg" ng-mousedown="mousedown2($event)">

JS:

$scope.mousedown2 = function($event) {
    console.log(angular.element($event.target).scope().p);
});

. forked plunk: http://plnkr.co/edit/7lGMphla42Chrg3X2NZl

+5

All Articles