fwi*_*tra 12 javascript backbone.js
我们有一个backbone.js应用程序,它向用户显示许多表单.我们想要的是非常简单:如果用户转到另一个页面而不保存填写的表单,我们想要显示一个确认对话框.
在经典形式中,这很容易,只需在jQuerysh中实现window.onbeforeunload(或$(window).on('beforeunload')).但骨干应用程序通常只有一个视图.我尝试使用onHashChange,但在该回调中返回false并不会阻止Backbone仍然转到另一个视图.
指针表示赞赏.搜索互联网并没有找到任何有效的回复.
我会避免使用Backbone进行攻击.您可以通过替换通常Backbone.history
以类似的方式开始的部分来全局地为所有链接执行此操作
initRouter: function () {
Backbone.history.start({ pushState: true });
$(document).on('click', 'a', function (ev) {
var href = $(this).attr('href');
ev.preventDefault();
if (changesAreSaved) {
router.navigate(href, true);
}
});
}
Run Code Online (Sandbox Code Playgroud)
当然,您需要更换changesAreSaved
有意义的内容并添加有关处理链接的其他任何登录信息.
我也会破解Backbone.history.loadUrl
,这就是加载路由回调的地方.
// ALLOW PREVENTING HASH NAVIGATION
var originalFn = Backbone.history.loadUrl;
Backbone.history.loadUrl = function() {
// I introduced an application state variable, but it can be solved in multiple ways
if (app && app.states.isNavigationBlocked) {
var previousFragment = Backbone.history.fragment;
window.location.hash = '#' + previousFragment;
return false;
}
else {
return originalFn.apply(this, arguments);
}
};
Run Code Online (Sandbox Code Playgroud)
Backbone监听hashchange
事件并设置Backbone.history.checkUrl
为回调:https:
//github.com/jashkenas/backbone/blob/1.1.2/backbone.js#L1414
Backbone.$(window).on('hashchange', this.checkUrl);
Run Code Online (Sandbox Code Playgroud)
Backbone.history.checkUrl
检查哈希是否已更改并调用 Backbone.history.loadUrl
checkUrl: function(e) {
var current = this.getFragment();
if (current === this.fragment && this.iframe) {
current = this.getFragment(this.getHash(this.iframe));
}
if (current === this.fragment) return false;
if (this.iframe) this.navigate(current);
this.loadUrl();
},
Run Code Online (Sandbox Code Playgroud)
Backbone.history.loadUrl
找到第一个匹配的路由并调用其回调:
loadUrl: function(fragment) {
fragment = this.fragment = this.getFragment(fragment);
return _.any(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment);
return true;
}
});
},
Run Code Online (Sandbox Code Playgroud)
实用说明:
Backbone.history.fragment
存储当前哈希,它已设置Backbone.history.loadUrl
,因此我们可以在hashchange
事件发生后访问它,但在路由器回调完成之前.
我想你可以破解Backbone.history.loadUrl(http://documentcloud.github.com/backbone/docs/backbone.html#section-137).我做了一个快速测试,每次更改页面时,此代码都会进行检查.您只想在有实际原因的情况下添加代码才能激活检查.
var goingBack = false;
function doCheck() {
// TODO: add code that checks the app state that we have unsaved data
return goingBack || window.confirm("Are you sure you want to change pages?");
}
var oldLoad = Backbone.History.prototype.loadUrl;
Backbone.History.prototype.loadUrl = function() {
if(doCheck()) {
return oldLoad.apply(this, arguments);
} else {
// change hash back
goingBack = true;
history.back();
goingBack = false;
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
您还必须处理window.onbeforeunload,因为用户可能仍然完全离开页面.