问题
It's pretty common thing, like if you click on inbox here here on stackoverflow. I'll be calling that dialog or whatever gets opened a thing.
Now there are two ways I know of to deal with this,
- you create an invisible overlay where only the element you opened has bigger zindex, and you close your thing by clicking on the overlay
- click event on the document, and you check upon clicking whether you clicked on your thing or outside it, in which case you close your thing.
In either case I'd ideally like to use ng-class
to add/remove class that would show/hide the thing.
Now how would I do this with angular, so it could be used on any component(thing) I might add. It's not like I have single modal, I might have quite a few different components, with different html structure, positioning and stuff.
Which approach would be better, document event, overlay or something completely else?
Since angular doesn't really have any reference to dom, document approach could be a problem, right, since I can't quite check whether I'm clicking on the thing element? Unless I'd give every thing the same class..
Overlay approach on the other hand doesn't require any reference to dom elements.
Both approaches would need a unique var at rootScope for that ng-class
to work.. which bring the question whether to use ng-class
or something custom..
Anyway just throwing my ideas out there, maybe I'm thinking about it wrong from the beginning, has anyone dealt with this before?
回答1:
The way I've tackled things like this before is using inheritedData
to communicate to the click handler whether it's in or out of the thing:
In the custom directive for the thing, add a data variable to the element, using jqLite data, say
element.data('myThing',true)
. If you want to distinguish between multiple instances of the the thing, you might need to use some uniquely generated key.In the same custom directive, in a click event handler on document.body, you can check
angular.element(event.target).inheritedData('myThing')
An example directive that uses this technique is below
app.directive('thing', function($document,$window) {
return {
restrict: 'E',
template: '<div><span>Inner thing</span></div>',
replace: true,
link: function(scope,element) {
element.data('thing',true);
angular.element($document[0].body).on('click',function(e) {
var inThing = angular.element(e.target).inheritedData('thing');
if (inThing) {
$window.alert('in');
} else {
$window.alert('out');
}
})
}
}
});
and can be seen in this Plunker http://plnkr.co/edit/bRDLcLoesM7Z0BIxKxYu?p=preview
来源:https://stackoverflow.com/questions/21385614/angular-js-closing-with-click-anywhere-but-on-the-element