I am trying to create a directive that only fires a click event if the element it is on is clicked. I do not want the click event to fire if a child element is clicked. This is what I have so far and seems to be doing the trick.
bizi.directive('bbStrictClick', [
function () {
return {
restrict: 'A',
replace: false,
scope: {
clicked: '&bbStrictClick'
},
link: function (scope, element, attrs, controller) {
element.click(function (event) {
if (event.target === element[0]) {
event.stopImmediatePropagation();
event.stopPropagation();
scope.clicked();
}
});
}
};
}
]);
The problem is I am using isolate scope and as a result I cannot add this directive to elements that have other directives using isolate scope. Is there a way to execute the function specified in the directive attribute value without using isolate scope?
Yes, using $scope.$eval:
https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$eval
bizi.directive('bbStrictClick', [
function () {
return {
restrict: 'A',
link: function (scope, element, attrs, controller) {
element.click(function (event) {
if (event.target === element[0]) {
event.stopImmediatePropagation();
event.stopPropagation();
scope.$eval(attrs.bbStrictClick);
}
});
}
};
}])
You could also use $parse to pre-parse the expression into a function, and then execute that function (basically what &
does).
EDIT: you could have a look at how ngClick is coded in angular's source code: https://github.com/angular/angular.js/blob/v1.3.14/src/ng/directive/ngEventDirs.js#L49