在嵌套的ng-click调用之间取消事件传播的最佳方法是什么?

cil*_*hex 180 angularjs

这是一个例子.假设我希望像许多网站一样覆盖图像.因此,当您单击缩略图时,整个窗口上会出现黑色叠加层,并且图像的较大版本将居中.点击黑色叠加层即可解散它; 单击图像将调用显示下一个图像的功能.

html:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage()"/>
</div>
Run Code Online (Sandbox Code Playgroud)

javascript:

function OverlayCtrl($scope) {
    $scope.hideOverlay = function() {
        // Some code to hdie the overlay
    }
    $scope.nextImage = function() {
        // Some code to find and display the next image
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,这种设置,如果你点击图片,都nextImage()与hideOverlay()被调用.但我想要的只是nextImage()被召唤.

我知道你可以在这个nextImage()函数中捕获和取消事件,如下所示:

if (window.event) {
    window.event.stopPropagation();
}
Run Code Online (Sandbox Code Playgroud)

...但我想知道是否有更好的AngularJS方法,不需要我使用此片段为叠加层内的元素添加所有函数的前缀.

Ste*_*wie 189

@JosephSilber所说的,或者将$ event对象传递给ng-click回调并停止其内部的传播:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
  <img src="http://some_src" ng-click="nextImage($event)"/>
</div>
Run Code Online (Sandbox Code Playgroud)
$scope.nextImage = function($event) {
  $event.stopPropagation();
  // Some code to find and display the next image
}
Run Code Online (Sandbox Code Playgroud)

  • 使用$ event.preventDefault(); 在v> 1.5 (8认同)
  • @KoolKabin我正在使用Angular 1.5.8和$ event.stopPropagation()仍然可以正常工作.但是,$ event.preventDefault()不起作用 (3认同)

Jos*_*ber 170

用途$event.stopPropagation():

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage(); $event.stopPropagation()" />
</div>
Run Code Online (Sandbox Code Playgroud)

这是一个演示:http://plnkr.co/edit/3Pp3NFbGxy30srl8OBmQ?p = preview

  • 简单而完美 (2认同)

Dav*_*sen 101

我喜欢使用指令的想法:

.directive('stopEvent', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            element.bind('click', function (e) {
                e.stopPropagation();
            });
        }
    };
 });
Run Code Online (Sandbox Code Playgroud)

然后使用如下指令:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage()" stop-event/>
</div>
Run Code Online (Sandbox Code Playgroud)

如果你愿意,你可以使这个解决方案更通用,就像对不同问题的回答:https://stackoverflow.com/a/14547223/347216

  • 优雅的解决方案,喜欢它. (4认同)
  • @EhteshChoudhury - "stop-event"是我在上面的JS片段中创建的新指令.在此处查看有关声明和使用指令的更多信息:https://docs.angularjs.org/guide/directive (3认同)
  • 有多种有效的解决方案,但我最喜欢这个,所以我选择它作为答案. (2认同)
  • 如果您的元素是动态添加/删除的,请不要忘记在元素中查看'$ destroy'事件,以便解除处理程序的绑定.例如,element.on('$ destroy',function(){/*在这里取消绑定*/}); (2认同)

Mic*_*per 30

有时候,这样做最有意义:

<widget ng-click="myClickHandler(); $event.stopPropagation()"/>
Run Code Online (Sandbox Code Playgroud)

我选择这样做是因为我不想myClickHandler()在其他许多地方停止事件传播.

当然,我可以在处理程序函数中添加一个布尔参数,但stopPropagation()更有意义true.

  • 我一直很喜欢这个版本,似乎元素的嵌套应该与我调用的函数无关 (2认同)

And*_*lov 7

这对我有用:

<a href="" ng-click="doSomething($event)">Action</a>

this.doSomething = function($event) {
  $event.stopPropagation();
  $event.preventDefault();
};
Run Code Online (Sandbox Code Playgroud)