【问题标题】:Capture and cancel angularJS $destroy event based on window.confirm() choice根据 window.confirm() 选择捕获并取消 angularJS $destroy 事件
【发布时间】:2017-10-04 01:45:56
【问题描述】:

我有一个表单,我在上面设置了一个事件监听器,看起来像这样

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事件被调用;让他们有机会留在页面上以保存他们的更改,或者按 OK 并继续他们的 stateChange,但代价是失去他们的工作。

eventListener 正常关闭,当按下OkCancel 时,if 语句可以正确识别。问题是,e.preventDefault 似乎并没有阻止 $destroy 循环或 stateChange 的发生。

如何防止 $destroy 循环发生?我是不是走错了路?

【问题讨论】:

  • 您可以挂钩状态更改,并防止这种情况发生,而不是防止组件被破坏。

标签: javascript jquery angularjs typescript


【解决方案1】:

我找到的解决方案要感谢 Jeff Huijsmans,他最初建议捕获状态变化而不是 $destroy 事件。他的建议确立了正确的思路,以生成对我有用的解决方案。

$stateChangeStart 在最新版本的 Angular 路由器中已被弃用,我最终不得不使用他们的 $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 没有寻找卸载事件。

我没有编写更多代码来解决卸载和表单检查等问题。我实现了一个非常简单的第 3 部分库来为我处理卸载检查。

jquery.are-you-sure 是一个出色的轻量级表单检查器和 onbeforeunload 事件处理程序,从我的代码中可以看出,它在我的控制器中使用起来非常简单。

总而言之,角度路由器$transitions API 正在监视 DOM 是否发生了卸载事件发生的转换变化。 jquery.are-you-sure 库正在监视 DOM 以查找 DOM IS 卸载的事件,例如导航到一个全新的域,或关闭浏览器选项卡/窗口。

* 我认识到通过$scope 访问我的表单的$isDirty 值是更好的做法,但我在查找访问它时遇到了问题。我认为这与应用程序的一般设置及其对 TypeScript 和类型文件的使用有关。我不敢说实话。但是这段代码运行得很好,所以我决定用它来运行。

【讨论】:

    【解决方案2】:

    为了了解表单是否脏,您可以通过$scope.formName 访问它并访问该对象的$dirty 属性。 即使您的代码因为类而工作正常,但这实际上是一种不好的做法,应该使用 $dirty。 顺便说一句,为什么不将事件绑定到window.onblur 和/或window.onbeforeunload 属性? 在您执行的方式中,代码是在调用 $destroy 时执行的,因此销毁已经开始。 我认为你应该改用其他事件来改变你的逻辑。

    您可以尝试阻止 $destroy 的传播访问 $event 并使用以下代码:

    $event.stopPropagation();

    但我仍然建议您使用其他事件,即使它会起作用。

    【讨论】:

    • 我不熟悉 window.onblur,但我会考虑实现它。 window.onbeforeunload 不起作用,因为 Angular 正在操纵 DOM 来更改页面,而不是离开当前文档。这就是导致我尝试捕捉 $destroy 事件的原因。
    • 如果您从页面导航到应用程序内部,您只需要拦截您的 statachange 事件。这要容易得多。
    • 我明白您的意思是离开页面,以便您的应用程序。状态更改事件,因此它是您问题的答案
    猜你喜欢
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    相关资源
    最近更新 更多