在backbone.js中切换视图时检查未保存的更改

时间:2013-07-26 15:11:42

标签: javascript backbone.js

我是Javascript和backbone.js的新手,所以希望我在这里缺少一些简单的东西。我正在尝试一些我发现的示例代码,它应该在允许用户导航到另一个页面之前检查未保存的更改。我在这里创建了一个JSfiddle:

http://jsfiddle.net/U43T5/4/

代码订阅了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.viewundefined,因此永远不会输入第二个if块。

我希望示例程序在离开页面之前始终要求确认(在我的示例程序中,我已将this.view.dirty设置为始终为true,这就是为什么它应该始终询问确认)。或者如果有更好的方法,我愿意接受替代方案。

2 个答案:

答案 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)视图并取消成功并取消函数作为参数的函数。