7

I really love how the new ng-click directive in Angular now automatically includes functionality for touch events. However, I am wondering if it is possible to access that touch-event service from my custom directive? I have lots of directives that require that I bind a click event to the given element, but I'm simply doing that using the typical jquery syntax (ex: element.on('click', function(){ ... })). Is there a way that I can bind an ng-click event to an element within a directive? Without having to manually put a ng-click tag on my element in the HTML of my view...?

I want to be able to harness the power of both click and touch events. I could obviously import a library (such as HammerJS or QuoJS) but I would prefer not to have to do that, especially since Angular is already doing it.

I can access the $swipe service and bind different elements to that, but is there a similar service for ngTouch?

For reference, this is an example of when I would want to do this:

mod.directive('datepicker', ['$timeout', function($timeout){
     return {
         link: function(scope, elem, attrs){
             var picker = new DatePicker();

             elem.on('click', function(e){
                 picker.show();
             });

             // I would rather do something like:
             // elem.on('ngTouch', function(){ ... });
             //
             // or even:
             // $ngTouch.bind(elem, {'click': ..., 'touch': ...});
         }
     }
}]);

UPDATE: As noted by below, the source code for the ng-click directive is here. Can anyone see a way to harness that code and turn it into a "bindable" service?

tennisgent
  • 14,165
  • 9
  • 50
  • 48
  • do you mean something like that: http://stackoverflow.com/questions/15279244/dynamically-add-directives-on-angularjs – akonsu Oct 17 '13 at 18:03
  • meaning, just wrapping the `elem` element in another element that has an `ng-click` attribute? or adding an `ng-click` attribute to the `elem` element? I guess those would work... but it seems kind of "hack-ish" (especially with the `$compile` issues mentioned in that post)... ideas? – tennisgent Oct 17 '13 at 18:21
  • as far as I understand, `ngTouch` module implements a replacement for the `ngClick` directive (see https://github.com/angular/angular.js/blob/master/src/ngTouch/directive/ngClick.js), try injecting `ngClickDirective` and do what this post proposes: https://groups.google.com/d/msg/angular/xBFABCLv4XI/maoKgWubzQ0J – akonsu Oct 17 '13 at 18:34
  • Ok, i like the idea. So I import the `'ngClickDirective'` into my custom directive, which gives me a `ngClickDirective` variable, but then what do I do with it? I just tried that and all the `ngClickDirective` object has in it is: `[{"priority":0,"name":"ngClick","restrict":"A"}]`...? – tennisgent Oct 17 '13 at 18:58

1 Answers1

8

I don't think that's quite the right approach. I'd approach this by using a template within your directive and then using ngTouch within that.

mod.directive('datepicker', ['$timeout', function ($timeout) {
     return {
         template: '<div ng-touch="doSomethingUseful()"></div>',

         link: function (scope, elem, attrs) {
             var picker = new DatePicker();

             scope.doSomethingUseful = function () {
                 // Your code.
             }
         }
     }
}]);

UPDATE

Full example with additional attributes on the directive element:

http://codepen.io/ed_conolly/pen/qJDcr

eddiec
  • 7,608
  • 5
  • 34
  • 36
  • I like this approach, but the problem is that I've got a number of other attributes on my directive element in the DOM. It looks like this: `
    `. So I would rather not use a template because then its going to replace the element I've written in the DOM... any ideas how to get around that?
    – tennisgent Oct 22 '13 at 21:05
  • That's for your directive anyway though, so should probably be passed through with scope: {}? – eddiec Oct 22 '13 at 21:12
  • Example here http://codepen.io/ed_conolly/pen/qJDcr The example shows having other attributes on the DOM and pulling them in to the directive. It sounds like thats the approach you want. – eddiec Oct 22 '13 at 21:39
  • Totally makes sense! I have written probably 50 directives in my angular days and never knew that you could bind directive attributes to the scope using that `scope: {}` syntax. I thought it was just for binding to controller scope properties. But after reviewing your example and looking at the docs, that's clearly how its intended. Thanks for the help! Well worth the 50pts to learn that. – tennisgent Oct 23 '13 at 13:32