Comme exercice pour le lecteur (moi), j'ai voulu essayer une directive personnalisée pour accomplir ceci. Voici ce que j'ai trouvé (après de nombreuses tentatives infructueuses) :
<ul ng-controller="ListController">
<li ng-repeat="item in items">
<div singleton-overlay>{{item.content}}</div>
</li>
</ul>
Un service est nécessaire pour stocker l'élément qui a actuellement la superposition, le cas échéant. (J'ai décidé de ne pas utiliser le contrôleur pour cela, car je pense qu'un 'service + directive' ferait un composant plus réutilisable qu'un 'contrôleur + directive').
service('singletonOverlayService', function() {
this.overlayElement = undefined;
})
Et la 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) {
// this is a bit odd... modifying DOM elsewhere
angular.element(singletonOverlayService.overlayElement.children()).remove();
}
element.append('<div>overlay: tweet, share, pin</div>')
singletonOverlayService.overlayElement = element;
jsFiddle : http://jsfiddle.net/mrajcok/ya4De/
Je pense que l'implémentation est un peu non conventionnelle, cependant... la directive ne modifie pas seulement le DOM associé à son propre élément, mais elle peut aussi modifier le DOM associé à l'élément qui a actuellement la superposition.
J'ai essayé de mettre en place des $watches sur la portée et de faire en sorte que le singleton stocke et modifie les objets de la portée, mais je n'ai pas réussi à déclencher les $watches lorsque j'ai changé la portée à l'intérieur de la fonction moveOrToggleOverlay.