Ilan lewin Ilan lewin - 2 months ago 14
AngularJS Question

How to override an ng-click directive to not automatically run $apply

Found some close questions , but not exactly the one I need to ask.

I have multiple elements with ng-click events.
For a majority of them (of a specific class), I don't need to actually run an angular digest cycle after click. The result of the click on these elements does not affect any scope variable (let's say for example they just print out a console.log).

What I want to do is to react conditionally to an ngClick, where say elements of a specific css class will not have the automatic $apply at the end.

Edit:

What I ended up doing was replace the ng-click, ng-mouseenter and ng-mouseleave with the corresponding javascript replacements.

I did this for two reasons:
1. I don't actually affect the scope variables on those clicks, so I don't need to run a digest after each (I have mouseenters, so you can imaging that generated a lot of digest cycles for no reason).
2. This is content that I load late in the page loading sequence from another source (ng-bind), so it has to be sanitized by angular and then compiled. This took a log of time (almost a second) because I have many such links, and that was holding back the display of the content.

Answer

While I highly recommend against this, as the $apply in your application shouldn't really be affecting anything (even performance). You'll have to create your own directive for this.

HTML

<div data-no-apply-click="myFunction()">
</div>

Javascript

.directive('noApplyClick', function($parse) {
  return {
    compile: function($element, attr) {
      var fn = $parse(attr['noApplyClick']);
        return function(scope, element, attr) {
          element.on('click', function(event) {
            fn(scope, {$event: event, $element: element });
          });
        };
    }
  };
});

JsFiddle: http://jsfiddle.net/gj54bjsh/