2016-02-25 32 views
3

内我有一个角度的应用程序中,点击SVG元素上改变其状态(在连接段翻转它的填充颜色之间)如何停止角度从D3

我也D3有线了处理click事件拖动同一个对象。

d3文档指出,它们在非空拖拽后停止点击事件,但是是否尝试停止传播ng-click仍在拾取click事件。

如果没有d3拖动,是否可以触发ng-click?

在附加片段中,我的期望是,如果您只需单击蓝色矩形,它将切换为黄色(并再次返回),但如果拖动它,则颜色不会改变。我发现,拖动结束颜色的变化。

var myApp = angular.module('app', []); 
 

 
myApp.controller('ctrl', function ($scope){ 
 
    //clicking rectangle toggles yellow background 
 
    $scope.isYellow = false; 
 
    
 
    var drag = d3.behavior.drag() 
 
     .on("drag", function(d,i) { 
 
      var el = d3.select(this); 
 
      var h = el.attr("height"); 
 
      var w = el.attr("width"); 
 
      var x = d3.event.x - (w/2); 
 
      var y = d3.event.y - (h/2); 
 
      el.attr("transform", "translate(" + [ x,y ] + ")") 
 

 
      //try to stop the event from propagating 
 
      d3.event.sourceEvent.stopPropagation(); 
 
      d3.event.preventDefault(); 
 
     }); 
 
    
 
    d3.select('rect').call(drag); 
 
});
svg {background:red} 
 
rect {fill:blue} 
 
.yellow {fill: yellow}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 

 
    <div ng-app="app"> 
 
    <svg width=250 height=250 ng-controller="ctrl"> 
 
     <rect 
 
      ng-class="{yellow : isYellow}" 
 
      ng-click="isYellow = !isYellow" 
 
      x="10" y="10" width="30" height="30"> 
 

 
     </rect> 
 
    </svg> 
 
    </div>

+0

你试过设置你的ng-click函数中的一个条件,比如'if($ scope.hasBeenDragged === false){doThing(); }',然后在你的d3'.on(“drag”,...)'块中设置'$ scope.hasBeenDragged = true;'? –

+0

@BennettAdams如果真实代码像这样紧密结合在一起,那么我们可以但我们实际上使用的是browserify,我试图让d3代码完全与Angular隔离。另外我讨厌添加状态/代码(如果我可以避免,它需要长时间维护和维护):) –

回答

5

正像人们常常只是制定问题长钉给了我足够的潜意识工作的情况。

d3 docs甚至有我只是没有意识到它

在拖拽手势的答案,一些浏览器的默认行为(如文本选择)被阻止。要允许拖动链接,可以防止紧跟在非空拖动手势之后的单击事件的默认行为。在可拖动元素上注册自己的点击侦听器时,可以检查点击事件是否被抑制如下:

selection.on(“click”,function(){ if(d3.event.defaultPrevented)return;/click suppress console.log(“clicked!”); });

在经过角的$eventng-click让我检查isDefaultPrevented其中D3拖动允许修改的方案为在这里的片段后是真的

var myApp = angular.module('app', []); 
 

 
myApp.controller('ctrl', function ($scope){ 
 
    //clicking rectangle toggles yellow background 
 
    $scope.isYellow = false; 
 
    
 
    $scope.toggleColour = function($event) { 
 
    if ($event.isDefaultPrevented()) { 
 
    return; 
 
    } 
 
    $scope.isYellow = !$scope.isYellow; 
 
    }; 
 

 
    var drag = d3.behavior.drag() 
 
     .on("drag", function(d,i) { 
 
      var el = d3.select(this); 
 
      var h = el.attr("height"); 
 
      var w = el.attr("width"); 
 
      var x = d3.event.x - (w/2); 
 
      var y = d3.event.y - (h/2); 
 
      el.attr("transform", "translate(" + [ x,y ] + ")") 
 

 
      //try to stop the event from propagating 
 
      d3.event.sourceEvent.stopPropagation(); 
 
      d3.event.preventDefault(); 
 
     }); 
 
    
 
    d3.select('rect').call(drag); 
 
});
svg {background:red} 
 
rect {fill:blue} 
 
.yellow {fill: yellow}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 

 
    <div ng-app="app"> 
 
    <svg width=250 height=250 ng-controller="ctrl"> 
 
     <rect 
 
      ng-class="{yellow : isYellow}" 
 
      ng-click="toggleColour($event)" 
 
      x="10" y="10" width="30" height="30"> 
 

 
     </rect> 
 
    </svg> 
 
    </div>