テーブル行にクリックイベントがあり、この行にはクリックイベントのある削除ボタンもあります。削除ボタンをクリックすると、行のクリックイベントも発生します。
これが私のコードです。
<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>
テーブルセルの削除ボタンをクリックしたときにshowUser
イベントが発生するのを防ぐにはどうすればよいですか?
ngClickディレクティブ(および他のすべてのイベントディレクティブ)は、同じスコープで利用可能な$event
変数を作成します。この変数はJSのevent
オブジェクトへの参照であり、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>
Stewieの答えに追加。あなたのコールバックが伝播を止めるべきかどうかを決定するとき、私はそれがコールバックに$event
オブジェクトを渡すことが有用であるとわかりました:
<div ng-click="parentHandler($event)">
<div ng-click="childHandler($event)">
</div>
</div>
そして、コールバック自体で、イベントの伝播を止めるべきかどうかを決めることができます。
$scope.childHandler = function ($event) {
if (wanna_stop_it()) {
$event.stopPropagation();
}
...
};
私はあなたがクリックが効果を及ぼす領域を制限することを可能にする指令を書きました。これは、このような特定のシナリオで使用される可能性があるため、ケースバイケースでクリックを処理する必要はなく、単に「クリックはこの要素から発生しない」と言うことができます。
あなたはこのようにそれを使うでしょう:
<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>
ボタンだけでなく、最後のセルに対するすべてのクリックが防止されることに注意してください。それがあなたが望まないものであるならば、あなたはこのようにボタンを包むことを望むかもしれません:
<span isolate-click>
<button class="btn" ng-click="deleteUser(user.id, $index);">
Delete
</button>
</span>
これがディレクティブのコードです。
angular.module('awesome', []).directive('isolateClick', function() {
return {
link: function(scope, elem) {
elem.on('click', function(e){
e.stopPropagation();
});
}
};
});
あなたが私のようなディレクティブを使用している場合、これはあなたが双方向のデータバインディングを必要とするときにどのように動作するかです。例えば、モデルやコレクションの属性を更新した後:
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')
});
});
}
}
}
これで、ボタン、リンク、divなどで簡単に使用できます。
<button set-survey-in-edition-mode >Edit survey</button>