Reputation: 2637
I want a directive that calls a function when clicking outside of the element. The use case it to have menu's opening onclick and closing when clicking outside of them.
The directive binds a onlick to the window to ckeck for clicks outside of the element but the onclick function gets the last scope, not the "right" scope
http://plnkr.co/edit/ePKMMsbe9HYikY9XQ1u3?p=preview
app.directive('clickanywherebuthere', ['$document', '$timeout', function($document, $timeout) {
return {
link: function postLink(scope, element, attrs) {
onClick = function(event) {
var isChild = element.has(event.target).length > 0;
var isSelf = element[0] == event.target;
var isInside = isChild || isSelf;
if (!isInside)
scope.$apply(attrs.clickanywherebuthere)
}
scope.$watch(attrs.isActive, function(newValue, oldValue) {
if (newValue !== oldValue && newValue == true) {
$timeout(function() { $document.bind('click', onClick) })
}
else if (newValue !== oldValue && newValue == false) {
$document.unbind('click', onClick);
}
});
}
};
}])
Upvotes: 1
Views: 83
Reputation: 689
Perhaps it is better not to listen for clicks outside a directive via the link function of the directive. I suggest you add a global listener for clicks on the page that broadcast the name of the element that is clicked on (of whatever you prefer) and make the directive listen for these events with scope.$on('name-of-event');
and in the run phase of your app, you add the click listener that broadcast the value of the clicked element
angular.module('test').run(function($rootScope){
$(document).click(function(event){
$rootScope.$broadcast('clickanywhere',event.target.nodeName)
})
})
Upvotes: 0
Reputation: 997
The problem is that onClick only gets created the first time your directive is called and it's bound to the first button's scope. You need to add "var" in front of "onClick" to make it work properly. I modified your plnkr below:
http://plnkr.co/edit/0TrIM6d1Y6mneYgMcCjN?p=preview
Upvotes: 1