Durandal canDeactivate vs window.onbeforeunload可能的替代方案

时间:2014-06-17 14:30:25

标签: javascript jquery single-page-application durandal onbeforeunload

用户可以编辑他们的个人资料信息。如果他们在存在更改时尝试离开页面,则所需的功能应该是它们带有确认框。当我使用Durandal的canDeactivate时,它仅在我尝试导航到另一个Durandal页面时触发。当我使用window.onbeforeunload时,只有当我硬刷新或输入新的URL等时才会触发它。

是否有任何通用的解决方案(统一的外观和感觉)可以捕获这两类事件,以防止用户立即离开页面?

我的两种方法如下所示:

Durandal canDeactivate

canDeactivate: function () {
        if ($("#saveButtonsBottom").css('visibility') === 'visible') {
            var title = 'Warning';
            var msg = 'Do you want to leave this page and lose all of your edits to this form?';
            return app.showMessage(msg, title, ['Yes', 'No'])
                .then(function (selectedOption) {
                    return selectedOption === 'Yes';
                });
        }
        return false;
    }

window.onbeforeunload

            window.onbeforeunload = function() {
            if ($("#saveButtonsBottom").css('visibility') === 'visible') {
                var title = 'Warning';
                var msg = 'Do you want to leave this page and lose all of your edits to this form?';
                return app.showMessage(msg, title, ['Yes', 'No'])
                    .then(function (selectedOption) {
                        return selectedOption === 'Yes';
                    });
            }
            return true;
        };

1 个答案:

答案 0 :(得分:1)

我在实践中发现,您需要两种方法来确保所需的行为。许多人认为window.onbeforeunload是Web应用程序的不良做法。

我们最终在我们的Web应用程序中放弃了这种方法,转而使用“正在进行中”模式,其中每3秒钟保存一次更改(发送到后端)。这样,用户可以自由地从一个页面移动到另一个页面而不必担心丢失他们的工作。它确实需要调整一个人的数据模型,并且能够关闭正在进行的工作的验证。项目文档集合 - 或项目表,取决于您的数据方法 - 将具有相应的ProjectDraft文档集合或表。

但这是另一个讨论的主题。与此同时,如果你必须采用你已经给出的方法,为什么不将逻辑封装在另一个需要的模块中呢?换句话说:

var onNavigateOrShutdown = function () {
    var title = 'Warning';
    var msg = 'Do you want to leave this page and lose all of your edits to this form?';
    return app.showMessage(msg, title, ['Yes', 'No'])
        .then(function (selectedOption) {
            return selectedOption === 'Yes';
        });
}

然后

canDeactivate: function () {
    if ($("#saveButtonsBottom").css('visibility') === 'visible') {
        onNavigateOrShutdown();
    return false;
}

window.onbeforeunload = function() {
    if ($("#saveButtonsBottom").css('visibility') === 'visible') {
        onNavigateOrShutdown();
    }
    return true;
};

现在,让我们将此功能转移到名为navigation.manager的新单例模块中。然后,只需要在任何需要此逻辑的地方都需要模块。当然,您可以详细说明navigation.manager并让它包含一个能够响应消息和/或发布消息的事件中心。