我已经设法找到了解决方案,尽管还需要做一些工作。对于此解决方案,我假设您在视图脏时进行跟踪。
有 4 种主要的移出视图的方式;
- 点击视图上的链接
- 点击视图外的链接
- 点击刷新或外部链接
- 在浏览器上单击后退/前进
1.申请链接
这是最简单的情况。当您单击自己的链接时,您必须检查您的视图是否脏。例如,我有一个由historyBack 函数处理的应用内后退按钮。论观点:
historyBack: function() {
if (this.isDirty) {
answer = confirm("There are unsaved changes.\n\nDo you wish to continue?")
if (answer) {
this.isDirty = false
window.history.back()
}
}
else {
window.history.back()
}
}
2。视图之外的链接
这种类型的交互可以通过扩展路由器原型的execute 方法来处理,而不是其他地方建议的navigate 方法。
应该有一个存储视图状态的路由器可以访问的变量。就我而言,我使用的是路由器本身,每次更改视图上的脏标志时都会更新此变量。
代码应如下所示:
_.extend(Backbone.Router.prototype, {
execute: function (callback, args, name) {
if (Backbone.Router.isDirty) {
answer = confirm "There are unsaved changes.\n\nDo you wish to continue?";
if (!answer) {
return false;
}
}
Backbone.Router.isDirty = false
if (callback) callback.apply(this, args)
}
}
3.刷新或外部链接
刷新和外部链接实际上卸载了您的 Javascript,因此这里基于 beforeunload 的解决方案(请参阅问题)实际工作。无论您在哪里管理视图,我都使用控制器,但我们假设它在同一个视图上,您在 show 上添加一个侦听器并在销毁时将其删除:
onShow: function() {
$(window).bind("beforeunload", function (e) {
if (this.isDirty) {
return "There are unsaved changes.";
}
}
}
onDestroy: function() {
$(window).unbind("beforeunload");
}
4.在浏览器上后退/前进
这是最棘手的情况,也是我尚未完全弄清楚的情况。后退/前进时,用户可以导航出应用程序或在应用程序内导航,这两种情况都包含在 1 和 3 的代码中,但是有一个问题我无法弄清楚,我将为其创建另一个问题.
点击后退/前进时,浏览器会在调用路由器之前更改地址栏,因此您最终会出现不一致的状态:地址栏显示到应用程序状态的不同路由。这是一个大问题,如果用户再次点击后退按钮,在保存或放弃更改后,她将被带到另一条路线,而不是上一条路线。
其他一切正常,它会显示一个弹出窗口,询问用户是要离开还是继续,如果用户选择留下,则不会重新加载视图。