Using ng-click vs bind within link function of Angular Directive
Solution 1
You may use a controller in directive:
angular.module('app', [])
.directive('appClick', function(){
return {
restrict: 'A',
scope: true,
template: '<button ng-click="click()">Click me</button> Clicked {{clicked}} times',
controller: function($scope, $element){
$scope.clicked = 0;
$scope.click = function(){
$scope.clicked++
}
}
}
});
More about directives in Angular guide. And very helpfull for me was videos from official Angular blog post About those directives.
Solution 2
I think it is fine because I've seen many people doing this way.
If you are just defining the event handler within the directive, you do not have to define it on the scope, though. Following would be fine.
myApp.directive('clickme', function() {
return function(scope, element, attrs) {
var clickingCallback = function() {
alert('clicked!')
};
element.bind('click', clickingCallback);
}
});
Solution 3
Shouldn't it simply be:
<button ng-click="clickingCallback()">Click me<button>
Why do you want to write a new directive just to map your click event to a callback on your scope ? ng-click already does that for you.
Comments
-
ehfeng almost 2 years
In the link function, is there a more "Angular" way to bind a function to a click event?
Right now, I'm doing...
myApp.directive('clickme', function() { return function(scope, element, attrs) { scope.clickingCallback = function() {alert('clicked!')}; element.bind('click', scope.clickingCallback); } });
Is this the Angular way of doing it or is it an ugly hack? Perhaps I shouldn't be so concerned, but I'm new to this framework and would like to know the "correct" way of doing things, especially as the framework moves forward.
-
Mark Rajcok over 11 yearsIn clickingCallback, if you are changing any model/scope data, you'll want to call scope.$apply(), or put the contents of the method inside scope.$apply(function() { ...contents here...});
-
ehfeng over 11 yearsI actually want to add the ng-click attribute to the element itself, not the template element (in your case, the button). Do you know how to do that?
-
ehfeng over 11 yearsNever mind, I figured it out - I can use the "replace" option within the directive.
-
turbo2oh almost 11 years@Maxim Grach why not just put the button HTML in the HTML? It seems like a lot of work to display a button that calls a controller method and less obvious when viewing the HTML. PS I'm learning angular as well.
-
Maxim Grach almost 11 years@turbo2oh this example is very simple and out of real life. But It shows how you can use angular directives.
-
JacobF about 10 yearsI'm also curious about the opions on this one.
ng-click
versuselement.bind()
-
Bill'o over 9 years@Maxim Grach I think that writing scope: {} would be more correct syntax-wise
-
Estevez about 9 yearsMaybe just to make that part reusabel, repeatable the code elsewhere.
-
Fred almost 9 years@MaximGrach using scope: {} would isolate the scope, while using true allows shared scope.
-
Alisson Reinaldo Silva about 7 years@Estevez that's exactly my use case.