我有一个表单,我在其上设置了一个看起来像这个
的事件监听器setExitCheck = () => {
this.$scope.$on('$destroy', (e) => {
if ($('#compForm').hasClass('ng-dirty')) {
if (window.confirm('You may have unsaved changes! Press ok to continue, or press cancel to go back and save your work.') === false) {
e.preventDefault();
}
}
});
};
这个想法是,如果表单是脏的并且具有ng-dirty
类,并且用户尝试启动stateChange并且调用$destroy
事件;让他们有机会留在页面上保存他们的更改,或者按好,然后以失去工作为代价继续他们的状态改变。
eventListener正常运行,if语句在按下Ok
或Cancel
时正确识别。问题是,e.preventDefault
似乎没有停止$ destroy循环,或者stateChange不会发生。
如何防止$ destroy循环发生?我可能会采取错误的方式吗?
答案 0 :(得分:0)
为了理解表单是否脏,您只需通过$scope.formName
访问它并访问该对象的$dirty
属性即可。
即使你的代码因为类而工作正常,它实际上也是一种不好的做法,应该使用$ dirty。
顺便说一下,为什么不将事件绑定到window.onblur
和/或window.onbeforeunload
属性?
在你执行的方式中,代码在$ destroy被调用时执行,因此破坏已经开始了。
我认为您应该使用其他事件来改变您的逻辑。
您可以尝试停止传播$ destroy访问$ event并使用以下代码:
$event.stopPropagation();
但是我仍然建议你使用其他事件,即使它会起作用。
答案 1 :(得分:0)
我找到的解决方案归功于Jeff Huijsmans,他最初建议捕获状态变化而不是$ destroy事件。他的建议确定了适当的思路,以产生适合我的解决方案。
在最新版本的角度路由器中已弃用 $stateChangeStart
,我最终不得不使用他们的$transitions
api。
现在代码看起来像这样,并按预期工作 *
setExitCheck = () => {
this.$transitions.onStart({}, () => {
if ($('#compForm').hasClass('ng-dirty')) {
if (window.confirm('You may have unsaved changes! Press ok to continue, or press cancel to go back and save your work.') === false) {
return false;
}
}
});
$('#compForm').areYouSure();
};
注意方法底部的一行$().areYouSure();
$ transitions api检查这个,在应用程序内部从未卸载文档的转换。由于这个原因,$ transitions api没有寻找卸载事件。
我没有编写更多代码来解释卸载和表单检查等问题。我实现了一个非常简单的第三方库来处理卸载检查。
jquery.are-you-sure是一个很棒的,轻量级的格式检查程序,以及onbeforeunload事件处理程序,在我的控制器中使用非常简单,就像我从代码中看到的那样。
总结角度路由器$transitions
API正在监控DOM,以便在卸载事件发生 NOT 时发生转换更改。并且jquery.are-you-sure库正在监视DOM,以便卸载DOM IS 的事件,例如导航到一个全新的域,或关闭浏览器选项卡/窗口。
* 我认为最好通过$isDirty
访问表单的$scope
值,但我遇到了查找访问权限的问题。我认为它与应用程序的一般设置及其对TypeScript和打字文件的使用有关。我不确定是否诚实。但是这段代码运行得非常好,所以我决定使用它。