我是Javascript和backbone.js的新手,所以希望我在这里缺少一些简单的东西。我正在尝试一些我发现的示例代码,它应该在允许用户导航到另一个页面之前检查未保存的更改。我在这里创建了一个JSfiddle:
代码订阅了hashchange事件,如下所示:
$(window).on("hashchange", router.hashChange);
router.hashChange
函数检查"脏"标志以确定是否允许导航,如下所示:
hashChange: function (evt) {
if (this.cancelNavigate) { // cancel out if just reverting the URL
evt.stopImmediatePropagation();
this.cancelNavigate = false;
return;
}
if (this.view && this.view.dirty) {
var dialog = confirm("You have unsaved changes. To stay on the page, press cancel. To discard changes and leave the page, press OK");
if (dialog == true) return;
else {
evt.stopImmediatePropagation();
this.cancelNavigate = true;
window.location.href = evt.originalEvent.oldURL;
}
}
},
问题是代码无效,因为this.view
是undefined
,因此永远不会输入第二个if块。
我希望示例程序在离开页面之前始终要求确认(在我的示例程序中,我已将this.view.dirty
设置为始终为true
,这就是为什么它应该始终询问确认)。或者如果有更好的方法,我愿意接受替代方案。
答案 0 :(得分:1)
主要问题是方法中的this
上下文,this
对应窗口对象,而不是路由器。因此,当您在路由器上定义视图时,它始终未定义。声明一个initialize方法,它将方法内的上下文绑定到路由器。
initialize: function() {
_.bindAll(this, 'loadView', 'hashChange');
},
<强> Check Fiddle 强>
答案 1 :(得分:0)
我花了很多时间来制作一些体面的东西。
我最终为Backbone函数编写了一个包装器:
var ignore = false;
Backbone.history.checkUrl = function() {
if (ignore) {
ignore = false;
return;
}
app.dirtyModelHandler.confirm(this, function () {
Backbone.History.prototype.checkUrl.call(Backbone.history);
},
function() {
ignore = true;
window.history.forward();
});
};
app.dirtyModelHandler.confirm是一个显示确认(Ok,Cancel)视图并取消成功并取消函数作为参数的函数。