Каков наилучший способ отменить распространение событий между вложенными вызовами ng-click?
Вот пример. Скажем, я хочу, чтобы изображение накладывалось подобно множеству сайтов. Поэтому, когда вы нажимаете миниатюру, над вашим окном появляется черная надпись, и в ней сосредоточена большая версия изображения. Щелчок на черном наложении отклоняет его; щелчок по изображению вызовет функцию, отображающую следующее изображение.
html:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
<img src="http://some_src" ng-click="nextImage()"/>
</div>
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
}
}
Проблема заключается в том, что при этой настройке, если вы щелкните изображение, вызываются как nextImage()
, так и hideOverlay()
. Но я хочу, чтобы вызывался только nextImage()
.
Я знаю, что вы можете захватывать и отменить событие в функции nextImage()
следующим образом:
if (window.event) {
window.event.stopPropagation();
}
... Но я хочу знать, есть ли лучший способ AngularJS сделать это, что не потребует от меня префикса всех функций на элементах внутри наложения с помощью этого фрагмента.
Ответы
Ответ 1
Что сказал @JosephSilber или передал объект $event в обратный вызов ng-click
и остановил его распространение внутри него:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
<img src="http://some_src" ng-click="nextImage($event)"/>
</div>
$scope.nextImage = function($event) {
$event.stopPropagation();
// Some code to find and display the next image
}
Ответ 2
Используйте $event.stopPropagation()
:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
<img src="http://some_src" ng-click="nextImage(); $event.stopPropagation()" />
</div>
Вот демо: http://plnkr.co/edit/3Pp3NFbGxy30srl8OBmQ?p=preview
Ответ 3
Мне нравится идея использовать для этого директиву:
.directive('stopEvent', function () {
return {
restrict: 'A',
link: function (scope, element, attr) {
element.bind('click', function (e) {
e.stopPropagation();
});
}
};
});
Затем используйте директиву как:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
<img src="http://some_src" ng-click="nextImage()" stop-event/>
</div>
Если бы вы хотели, вы могли бы сделать это решение более общим, как этот ответ, на другой вопрос: fooobar.com/questions/38474/...
Ответ 4
Иногда это может иметь смысл только для этого:
<widget ng-click="myClickHandler(); $event.stopPropagation()"/>
Я решил сделать это так, потому что я не хотел, чтобы myClickHandler()
останавливал распространение события во многих других местах, которые он использовал.
Конечно, я мог бы добавить логический параметр к функции обработчика, но stopPropagation()
гораздо более значим, чем просто true
.
Ответ 5
Это работает для меня:
<a href="" ng-click="doSomething($event)">Action</a>
this.doSomething = function($event) {
$event.stopPropagation();
$event.preventDefault();
};
Ответ 6
Если вы не хотите добавлять распространение останова ко всем ссылкам, это также работает. Немного более масштабируемым.
$scope.hideOverlay( $event ){
// only hide the overlay if we click on the actual div
if( $event.target.className.indexOf('overlay') )
// hide overlay logic
}
Ответ 7
Если вы вставляете ng-click = "$ event.stopPropagation" в родительский элемент вашего шаблона, stopPropogation будет пойман, поскольку он пузырится по дереву, так что вам нужно только написать его один раз для всего вашего шаблона.
Ответ 8
Вы можете зарегистрировать другую директиву поверх ng-click
, которая изменяет поведение по умолчанию ng-click
и останавливает распространение события. Таким образом, вам не нужно будет добавлять $event.stopPropagation
вручную.
app.directive('ngClick', function() {
return {
restrict: 'A',
compile: function($element, attr) {
return function(scope, element, attr) {
element.on('click', function(event) {
event.stopPropagation();
});
};
}
}
});
Ответ 9
В контроллере IN используется
$scope.methodName = function (event)
{event.stopPropagation();}