1

我是 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.viewis undefined,所以第二个 if 块永远不会输入。

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

4

2 回答 2

1

主要问题是this方法中的上下文,this对应于Window 对象而不是路由器。因此,当您在路由器上定义视图时,它始终保持未定义。声明一个将方法内部的上下文绑定到路由器的初始化方法。

 initialize: function() {
        _.bindAll(this, 'loadView', 'hashChange');
    },

检查小提琴

于 2013-07-26T17:42:11.917 回答
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 是一个显示确认(确定,取消)视图的函数,并将成功和取消函数作为参数。

于 2015-09-14T16:44:34.927 回答