如何防止 ng-click 在 label 标签上触发两次?
How to prevent ng-click's triggering twice on label tag?
当我单击其中包含输入的标签时,Angular 的 ng-click 会被触发两次。我试过 $event.stopPropagation();
但没用。我该如何解决?
我也检查了这个问题:
Angular.js ng-click events on labels are firing twice
<div class="list-group-item" ng-repeat="item in model.data">
<form role="form" name="selectForm" novalidate>
<label ng-click="$event.stopPropagation(); updateSelected();">
<input type="checkbox" ng-model="chechkedSkins[item.id]" />
<span>{{item.name}}</span>
</label>
</form>
</div>
使用ng-change="updateSelected"
仅在输入上使用此选项,因为即使您单击标签也会触发更改。
那是因为 label
是 checkbox
的父级或容器,所以 click
处理程序附加到您的情况下的完整容器,因此无论何时 label
或checkbox
被点击,事件被触发。
你的方法有什么问题:
- 首先,永远不要在标签内插入输入标签,这不是在 html.In 中构建标记的好方法
Angular.js
这种行为会导致两个标签的点击事件都被触发。所以要在 input
标签和 label
之间添加绑定,请使用标签的 for
属性。
- 在标签内部使用
$event.stopPropagation()
实际上会停止标签中从 propagating/boiling 到 DOM 顶部的所有事件。这不会起到任何作用,因为事件仍会传播到标签中的输入。
我希望你能想象我在说什么。
我做了什么:
- 使用
for
属性将 input
绑定到标签并添加 click
事件以阻止默认功能。
将点击处理程序添加到相应的 input
标记而不是 label
<label for="username" ng-click="$event.preventDefault();">Click me</label>
<input type="text" id="username" ng-click="updateSelected();">
这样你就不必担心事件处理中的任何冲突,也是维护 HTML 代码的巧妙方法 :)
我使用的是最新版本的 Angular Material 1.0.3,但在单击 Android 上配置为按钮的标签时仍然遇到此问题。我在 IOS 或浏览器(cordova 应用程序)上没有问题。以下为我解决了它。
我的html:
<label class="btn btn-primary" ng-click="vm.goAbout()">About</label>
我的控制器:
vm.goAbout = debounceFn(function(){
//show dialog here, and now it only pops up once
}, 250, false);
去抖功能:
function debounceFn(func, wait, immediate){
var timeout;
var deferred = $q.defer();
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if(!immediate) {
deferred.resolve(func.apply(context, args));
deferred = $q.defer();
}
};
var callNow = immediate && !timeout;
if ( timeout ) {
$timeout.cancel(timeout);
}
timeout = $timeout(later, wait);
if (callNow) {
deferred.resolve(func.apply(context,args));
deferred = $q.defer();
}
return deferred.promise;
}
}
Angular 的 ng-click 会被触发两次。我试过 $event.stopPropagation();
但没用。我该如何解决?
我也检查了这个问题: Angular.js ng-click events on labels are firing twice
<div class="list-group-item" ng-repeat="item in model.data">
<form role="form" name="selectForm" novalidate>
<label ng-click="$event.stopPropagation(); updateSelected();">
<input type="checkbox" ng-model="chechkedSkins[item.id]" />
<span>{{item.name}}</span>
</label>
</form>
</div>
使用ng-change="updateSelected"
仅在输入上使用此选项,因为即使您单击标签也会触发更改。
那是因为 label
是 checkbox
的父级或容器,所以 click
处理程序附加到您的情况下的完整容器,因此无论何时 label
或checkbox
被点击,事件被触发。
你的方法有什么问题:
- 首先,永远不要在标签内插入输入标签,这不是在 html.In 中构建标记的好方法
Angular.js
这种行为会导致两个标签的点击事件都被触发。所以要在input
标签和label
之间添加绑定,请使用标签的for
属性。 - 在标签内部使用
$event.stopPropagation()
实际上会停止标签中从 propagating/boiling 到 DOM 顶部的所有事件。这不会起到任何作用,因为事件仍会传播到标签中的输入。
我希望你能想象我在说什么。
我做了什么:
- 使用
for
属性将input
绑定到标签并添加click
事件以阻止默认功能。 将点击处理程序添加到相应的
input
标记而不是label
<label for="username" ng-click="$event.preventDefault();">Click me</label> <input type="text" id="username" ng-click="updateSelected();">
这样你就不必担心事件处理中的任何冲突,也是维护 HTML 代码的巧妙方法 :)
我使用的是最新版本的 Angular Material 1.0.3,但在单击 Android 上配置为按钮的标签时仍然遇到此问题。我在 IOS 或浏览器(cordova 应用程序)上没有问题。以下为我解决了它。
我的html:
<label class="btn btn-primary" ng-click="vm.goAbout()">About</label>
我的控制器:
vm.goAbout = debounceFn(function(){
//show dialog here, and now it only pops up once
}, 250, false);
去抖功能:
function debounceFn(func, wait, immediate){
var timeout;
var deferred = $q.defer();
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if(!immediate) {
deferred.resolve(func.apply(context, args));
deferred = $q.defer();
}
};
var callNow = immediate && !timeout;
if ( timeout ) {
$timeout.cancel(timeout);
}
timeout = $timeout(later, wait);
if (callNow) {
deferred.resolve(func.apply(context,args));
deferred = $q.defer();
}
return deferred.promise;
}
}