动态禁用元素中的所有ng-clicks

时间:2014-05-05 20:18:57

标签: angularjs angularjs-ng-click

我有一个指令disable-ng-clicks,在某些条件下,我想阻止作为该指令子级的所有ng-click。以下是一些示例标记:

<div disable-ng-clicks> <!-- directive -->
  <a ng-click="someAction()"></a>
  <div ng-controller="myController">
    <a ng-click="anotherAction()"></a>
    <a ng-click="moreActions()"></a>
  </div>
</div>

如果这些是正常的超链接,我可以在link函数中执行类似的操作:

function(scope, iElement, iAttrs) {
  var ngClicks = angular.element(iElement[0].querySelectorAll('[ng-click]'));
  ngClicks.on('click', function(event) {
    if(trigger) { // a dynamic variable that triggers disabling the clicks
      event.preventDefault();
    }
  });
}

但这对ng-click指令不起作用。还有另一种方法可以实现这个目标吗?

4 个答案:

答案 0 :(得分:1)

这是我能想到的最好的。我创建了一个新的指令来替换ng-click:

 directive('myClick', ['$parse', function($parse) {
  return {
    restrict: 'A',
    compile: function($element, attrs) {
      var fn = $parse(attrs.myClick);
      return function (scope, element, attrs) {
        var disabled = false;
        scope.$on('disableClickEvents', function () {
          disabled = true;
        });
        scope.$on('enableClickEvents', function () {
          disabled = false;
        });
        element.on('click', function (event) {
          if (!disabled) {
            scope.$apply(function () {
              fn(scope, { $event: event });
            });
          }
        });
      };
    }
  }
}]);

因此,在另一个指令中,我可以:

if (condition) { 
  scope.$broadcast('disableClickEvents');
}

当我想重新启用时:

if (otherCondition) { 
  scope.$broadcast('enableClickEvents');
}

我不喜欢为ng-click使用不同的指令,但这是我能想到的最好的计划。

答案 1 :(得分:0)

您正在捕捉&#39;点击&#39;由于JS events bubbling而在父级上的事件,所以如果你想在所有后代上拦截它,那么你的指令应该获得当前元素的所有后代,听他们点击&#39;事件并在必要时予以阻止。

答案 2 :(得分:0)

该指令将迭代所有子元素,检查它们是否具有ng-click属性,如果有,则会禁用任何已注册的click事件处理程序:

directive('disableNgClicks', function(){
  return {
    restrict: 'E',
    link: function(scope, elem, attrs){
      angular.forEach(elem.children(), function(childElem) {
        if (childElem.outerHTML.indexOf("ng-click") > -1) {
          angular.element(childElem).off('click');
        }
      });
    }
  }
})

Plunker demo

答案 3 :(得分:0)

我知道这是2年前,但我需要做类似的事情,并提出了一个相当简单的解决方案。

对象:

items: {
    item1 : {
        selected: 0,
        other: 'stuff'
    },
    item2 : {
        selected : 1,
        other: 'stuff'
    }  
}

HTML:

<div ng-repeat="item in items" ng-model="item.selected" ng-click="selectParent($event)">
    <div ng-click="item.selected ? selectChild($event) : null">Child</div>
</div>

功能:

$scope.selectParent = function($event) {
    var itemScope = angular.element($event.currentTarget)scope().item;
    itemScope.selected = !itemScope.selected;
}

$scope.selectChild = function($event) {
    $event.stopPropagation;
    console.log('I only get triggered if parent item is selected');
}

这是我所做的一个非常原始的例子。你可能应该使用一个指令,它给你$ scope而不是angular.element($ event.currentTarget).scope ......无论哪种方式,简单的内联,如果逻辑是我真正得到的。您可以根据某个值调用函数。