6

我正在尝试使用主干 js 构建一个切换视图,并在我切换视图几次时发现我的绑定事件被触发了多次。

以下是更好说明的代码:

html

<div id='container'>
    halo world
</div>

<button id='but1'>red view</button>
<button id='but2'>blue view</button>

css

#red_view{
    width:400px;
    height:400px;
    background-color:red;        
}
#blue_view{
    width:400px;
    height:400px;
    background-color:blue;        
}
.button,.button2{
    width:300px;
    height:300px;
    background-color:gray;
}

​ javascript

RedView = Backbone.View.extend({
    el: "#container",
    events:{"click .button":"clickme"},
    clickme:function(){
        alert('redview');                        
    },
    initialize: function(){
        this.$el.html("<div id='red_view'><div class='button'>Click Me</div></div>");            
    }
});

BlueView = Backbone.View.extend({
    el: "#container",
    events:{"click .button2":"clickme2"},
    clickme2:function(){
        alert('blueview');                        
    },    
    initialize: function(){
        this.$el.html("<div id='blue_view'><div class='button2'>Click Me</div></div>");            
    }
});

$(document).ready(function(){
    //var router = new SystemRouter();

    $('#but1').click(function(){
       var view = new RedView();
    });
    $('#but2').click(function(){
       var view = new BlueView();
    });    
});

如果您单击红色视图 3 次,然后按“单击我”。它也会弹出警报3次。我怀疑有必要在某处取消绑定事件,但找不到正确的方法来做到这一点。最好提供一些正确执行此操作的参考。

​这里是 jsfiddle 演示的链接。http://jsfiddle.net/mochatony/DwRRk/31/

4

3 回答 3

13

每次单击red view或- 按钮时,您每次blue view都会创建一个新的红色或蓝色视图。您绑定它们的事件哈希以响应源自具有类buttonbutton2.

  1. 按 'red view' 3 次 -> 创建了 3 个 RedView 实例
  2. 单击带有“按钮”类的按钮-> DOM 事件
  3. 3 个 RedView 实例监听所述 DOM 事件 -> 3 个警报

这是因为您在创建新视图之前没有清理视图,从而有效地留下了对事件做出响应的幽灵视图,即使它们不可见。(有关事件哈希的更多信息)您可以使用类似的方法从视图中清除事件。

cleanup: function() {
  this.undelegateEvents();
  $(this.el).clear();
}

这是您对视图进行清理的小提琴http://jsfiddle.net/DwRRk/34/

还有一个良好实践的提示:您应该使用诸如渲染方法之类的东西将东西附加到您的 DOM,使用初始化来初始化您的视图所需的值。

于 2012-06-26T07:58:31.657 回答
2

这是删除鬼视图的另一种方法(我正在使用的)

disposeView: function(view){
   Backbone.View.prototype.close = function () {
      this.unbind();
      this.undelegateEvents();
   };

   /* --Destroy current view */
   if(this.currentView !== undefined) {
      this.currentView.close();
   }

   /* --Create new view */
   this.currentView = view;
   this.currentView.delegateEvents();

   return this.currentView;
}

disposeView(new view());

请务必始终在您的视图中返回“this”,否则这将不起作用。

于 2013-02-19T02:06:47.820 回答
2

每次单击按钮时,您都会创建一个新视图,而不会破坏前一个视图。尝试使用像这样的单个视图:

http://jsfiddle.net/DwRRk/32/

var SomeModel = Backbone.Model.extend({});

var SomeView = Backbone.View.extend({
    el: "#container",
    model: SomeModel,
    events: {
        "click .button": "clickme"
    },
    clickme: function() {
        alert(this.model.get("color"));
    },
    colorChanged: function() {
        this.$el.html("<div id='" + this.model.get("color") + "_view'><div class='button'>Click Me</div></div>");
    },

    initialize: function() {
        _.bindAll( this, "colorChanged" );
        this.model.on("change:color", this.colorChanged );
        this.model.on("reset", this.colorChanged );
    }
});



$(document).ready(function() {
    //var router = new SystemRouter();
    var model = new SomeModel({color: "red"}),
        view = new SomeView({model: model})


    $('#but1').click(function() {
        model.set("color", "red");
    });
    $('#but2').click(function() {
        model.set("color", "blue");
    });
});​
于 2012-06-26T07:50:29.180 回答