根据window.confirm()选项捕获并取消angularJS $ destroy事件

时间:2017-05-05 14:16:46

标签: javascript jquery angularjs typescript

我有一个表单,我在其上设置了一个看起来像这个

的事件监听器
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语句在按下OkCancel时正确识别。问题是,e.preventDefault似乎没有停止$ destroy循环,或者stateChange不会发生。

如何防止$ destroy循环发生?我可能会采取错误的方式吗?

2 个答案:

答案 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和打字文件的使用有关。我不确定是否诚实。但是这段代码运行得非常好,所以我决定使用它。