Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h2>EDIT: There were a couple of problems in this old, old answer.</h2> <p><em>*Also: Marking Community Wiki (no points for me) because errors</em></p> <ol> <li><p>N calls for N uses of the directive. This probably isn't desirable for uses within the same scope with matching expressions.</p></li> <li><p>NOTHING WAS TEARING DOWN THE EVENT HANDLERS!!!! BAD! BAD! BAD! </p></li> </ol> <p>So, I'm updating this answer. Hopefully it didn't cause anyone too much trouble.</p> <h3>Updated answer</h3> <p><a href="http://plnkr.co/edit/kHvyDG1EEho4OkPhN7hJ?p=preview">Here's a new plunker with those issues fixed</a> ... there are likely other things that individual application developers will run into. This is just an example of how to handle this problem.</p> <pre><code>app.factory('clickAnywhereButHereService', function($document){ var tracker = []; return function($scope, expr) { var i, t, len; for(i = 0, len = tracker.length; i &lt; len; i++) { t = tracker[i]; if(t.expr === expr &amp;&amp; t.scope === $scope) { return t; } } var handler = function() { $scope.$apply(expr); }; $document.on('click', handler); // IMPORTANT! Tear down this event handler when the scope is destroyed. $scope.$on('$destroy', function(){ $document.off('click', handler); }); t = { scope: $scope, expr: expr }; tracker.push(t); return t; }; }); app.directive('clickAnywhereButHere', function($document, clickAnywhereButHereService){ return { restrict: 'A', link: function(scope, elem, attr, ctrl) { var handler = function(e) { e.stopPropagation(); }; elem.on('click', handler); scope.$on('$destroy', function(){ elem.off('click', handler); }); clickAnywhereButHereService(scope, attr.clickAnywhereButHere); } }; }); </code></pre> <h3>Original answer (with fixes for teardown of event handlers)</h3> <p>You were close with the one answer you've found, but I've <strong><a href="http://plnkr.co/edit/gqoNay?p=preview">put together a plunk</a></strong> for you to show you what it was missing.</p> <pre><code>app.directive('clickAnywhereButHere', function($document){ return { restrict: 'A', link: function(scope, elem, attr, ctrl) { var elemClickHandler = function(e) { e.stopPropagation(); }; var docClickHandler = function() { scope.$apply(attr.clickAnywhereButHere); }; elem.on('click', elemClickHandler); $document.on('click', docClickHandler); // teardown the event handlers when the scope is destroyed. scope.$on('$destroy', function() { elem.off('click', elemClickHandler); $document.off('click', docClickHandler); }); } } }) </code></pre> <p><strong>HTML</strong></p> <pre><code>&lt;a click-anywhere-but-here="clickedSomewhereElse()" ng-click="clickedHere()"&gt;Don't Click Me!&lt;/a&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload