作为读者(我)的练习,我想尝试使用自定义指令来完成此操作。这是我想出的(经过多次失败的尝试):
<ul ng-controller="ListController">
<li ng-repeat="item in items">
<div singleton-overlay>{{item.content}}</div>
</li>
</ul>
需要服务来存储当前具有覆盖的元素(如果有)。(我决定不为此使用控制器,因为我认为“服务+指令”会比“控制器+指令”更可重用。)
service('singletonOverlayService', function() {
this.overlayElement = undefined;
})
和指令:
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/
我认为这个实现有点不合常规,不过……该指令不仅修改了与它自己的元素相关联的 DOM,而且还可能修改了与当前具有覆盖的元素相关联的 DOM。
我尝试在作用域上设置 $watches 并让单例存储和修改作用域对象,但是当我从 moveOrToggleOverlay 函数内部更改作用域时,我无法触发 $watches。