如何关闭 body 单击 Angular 时的所有弹出窗口?

How to close out all popovers on body click in Angular?

http://plnkr.co/edit/hqXGl47EJ0wVaEgoXk3X?p=preview

我正在尝试找到完成此任务的最佳方法。基本上我们的应用程序中有几个弹出窗口,用于模糊搜索、附加选项、帮助提示等。

当它们中的任何一个打开时,如果用户点击它之外的任何其他地方,它们需要是可关闭的,比如 body。

vs.togglePopover = function() {
    vs.searchPopoverDisplay = vs.searchPopoverDisplay === false ? true: false;
};

我目前在body上的ng-click:

vs.closePopovers = function() {
    PopFactory.hidePopovers();
};

这会联系一个工厂服务,该服务获取所有 controllers/directives 具有弹出窗口的范围,如果它们是打开的,则关闭它们。

当然这会使弹出窗口无法使用,因为一旦您单击按钮打开弹出窗口,主 app.js 控制器就会检测到 body 单击并关闭它。

var hidePopovers = function() {
    searchPopover     = ScopeFactory.getScope('search');
    tagsSearchPopover = ScopeFactory.getScope('tagsPopover');
    tagsSortPopover   = ScopeFactory.getScope('tagsSearch');
    tagsPanel         = ScopeFactory.getScope('tagsPanel');

    // is this popover open?
    // if so close it, see the problem?
    if (searchPopover.searchPopoverDisplay) {
        searchPopover.searchPopoverDisplay = false;
    }

    if (tagsSearchPopover.tagSearchPopover) {
        tagsSearchPopover.tagSearchPopover = false;
    }

    if (tagsSortPopover.tagsPopoverDisplay) {
        tagsSortPopover.tagsPopoverDisplay = false;
    }

    if (tagsPanel.showingTagSearchInput) {
        tagsPanel.showingTagSearchInput = false;
    }
};

return {
    hidePopovers : hidePopovers
};

此功能在带有弹出窗口的应用中通常如何处理?

为什么不使用事件?

点击:

vs.closePopovers = function() {
    $rootScope.$broadcast('closeAllPopovers');
};

然后,在每个弹出窗口的范围内:

scope.$on('closeAllPopovers', function(){
    close(); // Or however you close a popover
});

Angular Documentation for $on


使用评论中链接的 Plunk:

单击按钮时,您可以看到来自按钮单击和正文单击的日志消息(顺便说一句,日志记录做得很好)。这意味着您对按钮的单击由按钮(打开弹出窗口)和正文(关闭弹出窗口)处理。

看看这个Plunk

要停止此行为,您需要告诉 ng-click 事件停止向上传播元素的层次结构。值得庆幸的是,一旦您知道该怎么做,这将非常容易。 Related SO Question(我更喜欢第二个答案,我不喜欢.html中的多余代码)