我一直在考虑修改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上添加内容?
答案 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;
});