当我点击"添加新项目"按钮我想要显示一个弹出窗体。
然后,如果我在此表单外单击,我希望它隐藏自己。
要显示/隐藏表单,我使用ng-show
指令。要注意外部点击,我使用第三方Angular指令angular-clickout但是有一个问题 - 这个指令开始处理页面加载,当我点击"添加新项目"按钮它立即调用我的关闭函数,然后将布尔属性设置为false值,ng-show
隐藏一个表单...
HTML:
<button ng-click="vm.displayDialogAddNewItem()>Add New Item</button>
<div class="new-item-dialog"
ng-show="vm.dialogAddNewItemIsVisible"
click-out="vm.hideDialogAddNewItem()">
... omitted code ...
</div>
控制器代码:
vm.displayDialogAddNewItem = function() {
vm.dialogAddNewItemIsVisible = true;
};
vm.hideDialogAddNewItem = function() {
vm.dialogAddNewItemIsVisible = false;
};
答案 0 :(得分:1)
您需要阻止事件冒泡DOM树,从而阻止父处理程序(在关闭模式的窗口上)被通知事件。
<!-- Pass the $event to the handler -->
<button ng-click="vm.displayDialogAddNewItem($event)>Add New Item</button>
JS
vm.displayDialogAddNewItem = function($event) {
vm.dialogAddNewItemIsVisible = true;
$event.stopPropagation(); // Stop bubbling up.
};
答案 1 :(得分:0)
这与事件在JavaScript中的工作方式有关。
假设你有这个HTML:
<div id="content">
<input type="button />
</div>
如果单击该按钮,则会生成单击事件。该事件将在捕获阶段(自上而下)开始,从window
开始,然后是div#content
,然后是按钮。然后冒泡阶段开始(自下而上),首先是按钮,然后是div#content
然后是window
。
默认情况下事件会附加到冒泡阶段,因此您的按钮会收到click事件,显示弹出窗口,然后窗口会收到点击并隐藏弹出窗口。这有点不方便。
解决此问题的一种方法是使用stopPropagation
来阻止事件冒泡。这种方法存在一些问题。例如,如果你有两个可以产生弹出窗口的按钮。单击button1然后button2将不会关闭第一个弹出窗口,因为共享父节点从未看到任何单击事件。
另一种解决方案是在捕获阶段添加弹出窗口关闭。当你想阻止弹出窗口点击关闭弹出窗口时,会出现一个潜在的问题。在捕获阶段难以确定该块。另一个解决方案是在捕获阶段标记事件,并延迟关闭到泡沫阶段(允许弹出窗口抛出一个块)。然而,这与stopPropagation
不太匹配。任何带有stopPropagation
的元素都会导致弹出窗口更接近失败,因为事件永远不会再冒出来。
另一种方法是让弹出处理程序知道它应该忽略下一次单击。 stopPropagation
再次有可能在这里造成伤害。例如,当id#content
上有stopPropagation
时。
你还可以使用某种setTimeout
技巧来延迟弹出窗口的渲染,直到click事件完成它的冒泡阶段。这有效,但感觉就像一个可怕的黑客。
正如你从这个相当精细的答案中看到的那样,这是我遇到的一个问题,并且已经考虑了很多。我还不知道解决方案。每个解决方案似乎都存在问题。我已经决定 stopPropagation
不好。我的理由是stopPropagation
打破了模块性。子节点可以在没有父母同意或知情的情况下影响父节点的行为,这似乎是一个问题。