如何防止ng-click在标签标签上触发两次?

时间:2015-09-01 11:10:43

标签: javascript jquery html angularjs angularjs-ng-click

当我点击其中包含输入的标签时,

Agnular的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>

3 个答案:

答案 0 :(得分:7)

使用ng-change="updateSelected"

仅在输入上使用此选项,因为即使单击标签也会触发更改。

答案 1 :(得分:5)

那就是因为labelcheckbox的父级或容器,所以click处理程序附加到您的案例中的完整容器,因此只要label {}或点击checkbox,触发事件。

您的方法出了什么问题:

  • 首先不要在标签内插入输入标签,这不是在html中构建标记的好方法。在Angular.js中,这种行为会导致两个标签都触发click事件。所以要在input标签和&amp;之间添加绑定label使用标签的for属性。
  • 在标签内使用$event.stopPropagation()实际上会阻止所有事件从标签传播/沸腾到DOM的顶部。这不会起任何作用,因为事件仍会传播到标签中的输入。

我希望你能想象出我在说什么。

我做了什么:

  • 使用for属性将input绑定到标签&amp;添加click事件以阻止默认功能。
  • 将点击处理程序添加到相应的input标记&amp;不是label

    <label for="username" ng-click="$event.preventDefault();">Click me</label> <input type="text" id="username" ng-click="updateSelected();">

Live Demo @ JSFiddle

通过这种方式,您不必担心事件处理中的任何冲突,以及维护HTML代码的简洁方法:)

答案 2 :(得分:1)

我使用的是最新版本的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;
       }
  }