thetallweeks thetallweeks - 29 days ago 5
AngularJS Question

Dynamically disable all ng-clicks within an element

I have a directive

disable-ng-clicks
and under certain conditions, I want to prevent all ng-clicks that are children of the directive. Here is some example markup:

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


If these were normal hyperlinks, I could do something like this in the
link
function:

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();
}
});
}


But this does not work for
ng-click
directives. Is there another way to accomplish this?

Answer

Here is the best I could come up with. I created a new directive to replace 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 });
            });
          }
        });
      };
    }
  }
}]);

So in a different directive, I can have:

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

and when I want to re-enable:

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

I don't like having to use a different directive for ng-click, but this is the best plan I could think of.

Comments