javascript - ng-click function
AngularJS ng-click stopPropagation (5)
En caso de que esté utilizando una directiva como yo, así es como funciona cuando necesita el enlace de dos vías de datos, por ejemplo, después de actualizar un atributo en cualquier modelo o colección:
angular.module(''yourApp'').directive(''setSurveyInEditionMode'', setSurveyInEditionMode)
function setSurveyInEditionMode() {
return {
restrict: ''A'',
link: function(scope, element, $attributes) {
element.on(''click'', function(event){
event.stopPropagation();
// In order to work with stopPropagation and two data way binding
// if you don''t use scope.$apply in my case the model is not updated in the view when I click on the element that has my directive
scope.$apply(function () {
scope.mySurvey.inEditionMode = true;
console.log(''inside the directive'')
});
});
}
}
}
Ahora, puedes usarlo fácilmente en cualquier botón, enlace, div, etc. así:
<button set-survey-in-edition-mode >Edit survey</button>
Tengo un evento de clic en una fila de la tabla y en esta fila también hay un botón de eliminación con un evento de clic. Cuando hago clic en el botón Eliminar, también se activa el clic en Evento en la fila.
Aquí está mi código.
<tbody>
<tr ng-repeat="user in users" class="repeat-animation" ng-click="showUser(user, $index)">
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>{{user.email}}</td>
<td><button class="btn red btn-sm" ng-click="deleteUser(user.id, $index)">Delete</button></td>
</tr>
</tbody>
¿Cómo puedo evitar que el evento showUser
se showUser
cuando showUser
clic en el botón Eliminar en la celda de la tabla?
Escribí una directiva que le permite limitar las áreas donde un clic tiene efecto. Podría usarse para ciertos escenarios como este, por lo que, en lugar de tener que lidiar con el clic caso por caso, puede decir simplemente que "los clics no saldrán de este elemento".
Lo usarías así:
<table>
<tr ng-repeat="user in users" ng-click="showUser(user)">
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td isolate-click>
<button class="btn" ng-click="deleteUser(user.id, $index);">
Delete
</button>
</td>
</tr>
</table>
Tenga en cuenta que esto evitaría todos los clics en la última celda, no solo el botón. Si eso no es lo que quieres, puedes envolver el botón así:
<span isolate-click>
<button class="btn" ng-click="deleteUser(user.id, $index);">
Delete
</button>
</span>
Aquí está el código de la directiva:
angular.module(''awesome'', []).directive(''isolateClick'', function() {
return {
link: function(scope, elem) {
elem.on(''click'', function(e){
e.stopPropagation();
});
}
};
});
La directiva ngClick (así como todas las demás directivas de eventos) crea la variable $event
que está disponible en el mismo ámbito. Esta variable es una referencia al objeto de event
JS y se puede usar para llamar a stopPropagation()
:
<table>
<tr ng-repeat="user in users" ng-click="showUser(user)">
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>
<button class="btn" ng-click="deleteUser(user.id, $index); $event.stopPropagation();">
Delete
</button>
</td>
</tr>
</table>
Una adición a la respuesta de Stewie. En el caso de que su devolución de llamada decida si la propagación debe detenerse o no, encontré útil pasar el objeto $event
a la devolución de llamada:
<div ng-click="parentHandler($event)">
<div ng-click="childHandler($event)">
</div>
</div>
Y luego, en la propia devolución de llamada, puede decidir si se debe detener la propagación del evento:
$scope.childHandler = function ($event) {
if (wanna_stop_it()) {
$event.stopPropagation();
}
...
};
<ul class="col col-double clearfix">
<li class="col__item" ng-repeat="location in searchLocations">
<label>
<input type="checkbox" ng-click="onLocationSelectionClicked($event)" checklist-model="selectedAuctions.locations" checklist-value="location.code" checklist-change="auctionSelectionChanged()" id="{{location.code}}"> {{location.displayName}}
</label>
$scope.onLocationSelectionClicked = function($event) {
if($scope.limitSelectionCountTo && $scope.selectedAuctions.locations.length == $scope.limitSelectionCountTo) {
$event.currentTarget.checked=false;
}
};