在AngularJs中修饰ng-click指令

时间:2013-08-20 12:51:45

标签: angularjs angularjs-directive decorator angularjs-ng-click

我一直在考虑修改AngularJS ng-click指令以添加一些额外的功能。我对使用它有什么不同的想法,但一个简单的方法是将Google Analytics跟踪添加到所有ng-click,另一个是防止双击。

要做到这一点,我的第一个想法就是使用装饰器。所以像这样:

app.config(['$provide', function($provide) {
  $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
    // Trigger Google Analytics tracking here
    return $delegate;
  }]);
}]);

但是这不会起作用,因为装饰器会在实例化时触发,而不是在满足指令中的表达式时触发。因此,在这种情况下,它会在带有指令的元素加载时进行分析,而不是在单击元素时进行分析。

关于真正的问题。装饰器是否有某种方法可以获得指令实例化的元素?如果我可以,从委托,到达元素我可以绑定我自己的点击事件,除了ng-click之外还要触发。

如果没有,您将如何在所有ng-clicks上添加内容?

2 个答案:

答案 0 :(得分:18)

你当然可以使用装饰器来添加功能。我已经快速plunkr来演示如何。基本上,在装饰器主体中,用自己的自定义逻辑替换编译函数(在示例中,如果存在track属性,则绑定到click事件),然后调用原始编译函数。这是片段:

$provide.decorator('ngClickDirective', function($delegate) {
  var original = $delegate[0].compile;
  $delegate[0].compile = function(element, attrs, transclude) {
    if(attrs.track !== undefined) {
      element.bind('click', function() {
        console.log('Tracking this');
      });
    }
    return original(element, attrs, transclude);
  };
  return $delegate;
})

答案 1 :(得分:6)

这是正确的更新版本(从答案中改进):

$provide.decorator('ngClickDirective', function($delegate) {
    var compile = $delegate[0].compile;
    $delegate[0].compile = function() {
       var link = compile.apply(this, arguments);
       return function(scope, element, attrs, transclude) {
           if (attrs.track !== undefined) {
               element.bind('click', function() {
                   console.log('Tracking this');
               });
           }
           return link.apply(this, arguments);
       };
    };
    return $delegate;
});