如何关闭 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
});
使用评论中链接的 Plunk:
单击按钮时,您可以看到来自按钮单击和正文单击的日志消息(顺便说一句,日志记录做得很好)。这意味着您对按钮的单击由按钮(打开弹出窗口)和正文(关闭弹出窗口)处理。
看看这个Plunk
要停止此行为,您需要告诉 ng-click 事件停止向上传播元素的层次结构。值得庆幸的是,一旦您知道该怎么做,这将非常容易。 Related SO Question(我更喜欢第二个答案,我不喜欢.html中的多余代码)
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
});
使用评论中链接的 Plunk:
单击按钮时,您可以看到来自按钮单击和正文单击的日志消息(顺便说一句,日志记录做得很好)。这意味着您对按钮的单击由按钮(打开弹出窗口)和正文(关闭弹出窗口)处理。
看看这个Plunk
要停止此行为,您需要告诉 ng-click 事件停止向上传播元素的层次结构。值得庆幸的是,一旦您知道该怎么做,这将非常容易。 Related SO Question(我更喜欢第二个答案,我不喜欢.html中的多余代码)