0

假设我有一个模型和一个视图,这个视图有两个方法:一个是绑定文档 mousemove 事件,另一个是 unbind 方法,默认我给文档 mousemove 事件,一旦模型的enable值改变我会调用视图的 unbind 方法:

    window.ConfigModel = Backbone.Model.extend({
        defaults: {
            'enable':0
        },
        initialize: function(){
            this.bind("change:enable", function () {
                var portView2 = new PortView();
                portView2.viewOff();                        
            });
        },
        change:function () {
            this.set('enable', 9);
        }
     })

    window.PortView = Backbone.View.extend({
        viewOn: function () {
            $(document).on('mousemove', function () {
                console.log('move')
            })
        },
        viewOff: function () {
            $(document).off('mousemove');
        }
    })

然后我input在文档上放了一个调用模型改变的:

    $('input').click(function () {
        var configModel = new ConfigModel();
        configModel.change();
    })

启动脚本是:

var portView1 = new PortView();
portView1.viewOn();

问题是一旦我调用点击输入按钮,chrome会告诉我一个错误:Maximum call stack size exceeded似乎change被调用了很多次。那么我的问题是什么问题,我该如何解决这个问题

4

1 回答 1

1

骨干模型已经有一个change方法

改变 model.change()

手动触发"change"事件并"change:attribute"为每个已更改的属性触发一个事件。如果您一直在传递{silent: true}给 set 函数以聚合对模型的快速更改,那么您将需要model.change()在全部完成后调用。

大概 Backbone 中的某些东西正在尝试调用configModel.change()并获取您的版本,change该版本会触发change()Backbone 中的另一个调用,该调用运行您的changewhich ...直到堆栈爆炸。

change您应该为您的方法使用不同的名称。


也就是说,您的代码结构有些奇怪。监听自身事件的模型很好,但创建视图的模型很奇怪:

initialize: function() {
    this.bind("change:enable", function () {
        var portView2 = new PortView();
        portView2.viewOff();                        
    });
}

实例化一个视图只是为了调用一个方法然后把它扔掉是很奇怪的,就像创建一个新模型只是为了触发一个事件一样。

我认为您可能希望将单个 ConfigModel 实例作为应用程序状态的一部分,例如app.config. 然后您的click处理程序将与该模型对话:

$('input').click(function () {
    app.config.enable_level_9(); // or whatever your 'change' gets renamed to
});

然后,您将拥有应用程序的其他部分(不一定是视图)来侦听更改app.config并采取适当的行动:

app.viewOn = function() {
    $(document).on('mousemove', function() {
        console.log('move')
    });
};
app.viewOff = function() {
    $(document).off('mousemove');
};
app.init = function() {
    app.config = new ConfigModel();
    app.viewOn();
    $('input').click(function () {
        app.config.enable_level_9();
    });
    // ...
};

然后通过一次app.init()调用启动应用程序:

$(function() {
    app.init();
});
于 2012-06-18T02:47:58.677 回答