As an exercise for the reader (me), I wanted to try a custom directive to accomplish this. Here is what I came up with (after many unsuccessful attempts):
<ul ng-controller="ListController"> <li ng-repeat="item in items"> <div singleton-overlay>{{item.content}}</div> </li> </ul>
To store an item that currently has an overlay, a service is required, if any. (I decided not to use a controller for this, since I think that the "service + directive" will make a more reusable component than the "directive + controller".)
service('singletonOverlayService', function() { this.overlayElement = undefined; })
And the directive:
directive('singletonOverlay', function(singletonOverlayService) { return { link: function(scope, element, attrs) { element.bind('click', moveOrToggleOverlay); function moveOrToggleOverlay() { if (singletonOverlayService.overlayElement === element) { angular.element(element.children()).remove(); singletonOverlayService.overlayElement = undefined; } else { if (singletonOverlayService.overlayElement != undefined) {
jsFiddle: http://jsfiddle.net/mrajcok/ya4De/
I think the implementation is a bit unconventional, though ... the directive not only modifies the DOM associated with its own element, but can also modify the DOM associated with the element that currently has an overlay.
I tried setting up $ watchs scope and possessing singleton storage and changing scope objects, but I couldn't get $ watch to run when I changed the scope inside the moveOrToggleOverlay function.
source share