Backbone.js:不删除事件的取消LegateEvents

Backbone.js:不删除事件的取消LegateEvents,backbone.js,backbone-views,Backbone.js,Backbone Views,在以下代码中: HTML <div id="myView"> <button id="test_button"> Test Button </button> <ul id="output"></ul> </div> 在主干视图的initialize()方法中,是否不从视图的先前实例化中删除先前委派的事件 上述代码的JSFIDLE示例:我将尽量不大声喊叫,但请停止尝试将视图绑定到现有元素。让视图创建并拥有

在以下代码中:

HTML

<div id="myView">
  <button id="test_button">
    Test Button
  </button>
  <ul id="output"></ul>
</div>
在主干视图的initialize()方法中,是否不从视图的先前实例化中删除先前委派的事件


上述代码的JSFIDLE示例:

我将尽量不大声喊叫,但请停止尝试将视图绑定到现有元素。让视图创建并拥有自己的
el
,然后调用
view.remove()。这个简单的更改解决了视图事件的许多问题,如果不这样做,您应该三思而后行

在您的情况下,您可以使用如下HTML:

<script id="t" type="text/x-underscore">
  <div id="myView">
    <button id="test_button">
      Test Button
    </button>
  </div>
</script>
<div id="container">
</div>
<ul id="output"> <!-- This is outside the container because we're going to empty and refill it -->
</ul>
var myView = Backbone.View.extend({
  events: {
    'click #test_button': 'buttonClicked'
  },
  render: function() {
    this.$el.html($('#t').html());
    return this;
  },
  buttonClicked: function() {
    $("#output").append('<li>Button was clicked</li>'); 
  }
});

$(document).ready(function(){
  var v = new myView();
  $('#container').append(v.render().el);

  v.remove(); // <----------------- Clean things up before adding a new one

  v = new myView();
  $('#container').append(v.render().el);
});
每个视图实例的
cid
都是唯一的,因此每个视图实例对
delegateEvents
绑定的事件使用其自己的唯一命名空间。这意味着:

this.undelegateEvents();
this.delegateEvents();
他说:

  • 删除此视图实例绑定的事件。这些事件将在
    '.delegateEvents'+此.cid
    命名空间中找到,其中
    cid
    对于每个视图实例都是唯一的
  • 绑定此视图实例定义的事件(或
    delegateEvents
    调用中的事件)。这些事件将使用
    '.delegateEvents'+this.cid
    命名空间附加
  • 因此,您的
    undelegateEvents
    调用正在删除事件,但不是所有事件,只删除视图实例添加的特定事件绑定

    您的
    this.undelegateEvents()
    调用实际上没有完成任何事情,因为它位于错误的位置,并且在错误的时间被调用。如果
    新视图
    调用方执行了
    取消删除事件
    调用:

    var v = new myView({el: "#myView"});    
    v.undelegateEvents();
    new myView({el: "#myView"});
    

    然后它会在正确的时间和地点发生。当然,这意味着您的路由器需要跟踪当前视图,以便能够在正确的时间
    currentView.undelegateEvents()
    ;但是如果你这样做的话,你最好(依我看)采用我在答案顶部概述的方法。

    我会尽量不大喊大叫,但请停止尝试将视图绑定到现有元素。让视图创建并拥有自己的
    el
    ,然后调用
    view.remove()。这个简单的更改解决了视图事件的许多问题,如果不这样做,您应该三思而后行

    在您的情况下,您可以使用如下HTML:

    <script id="t" type="text/x-underscore">
      <div id="myView">
        <button id="test_button">
          Test Button
        </button>
      </div>
    </script>
    <div id="container">
    </div>
    <ul id="output"> <!-- This is outside the container because we're going to empty and refill it -->
    </ul>
    
    var myView = Backbone.View.extend({
      events: {
        'click #test_button': 'buttonClicked'
      },
      render: function() {
        this.$el.html($('#t').html());
        return this;
      },
      buttonClicked: function() {
        $("#output").append('<li>Button was clicked</li>'); 
      }
    });
    
    $(document).ready(function(){
      var v = new myView();
      $('#container').append(v.render().el);
    
      v.remove(); // <----------------- Clean things up before adding a new one
    
      v = new myView();
      $('#container').append(v.render().el);
    });
    
    每个视图实例的
    cid
    都是唯一的,因此每个视图实例对
    delegateEvents
    绑定的事件使用其自己的唯一命名空间。这意味着:

    this.undelegateEvents();
    this.delegateEvents();
    
    他说:

  • 删除此视图实例绑定的事件。这些事件将在
    '.delegateEvents'+此.cid
    命名空间中找到,其中
    cid
    对于每个视图实例都是唯一的
  • 绑定此视图实例定义的事件(或
    delegateEvents
    调用中的事件)。这些事件将使用
    '.delegateEvents'+this.cid
    命名空间附加
  • 因此,您的
    undelegateEvents
    调用正在删除事件,但不是所有事件,只删除视图实例添加的特定事件绑定

    您的
    this.undelegateEvents()
    调用实际上没有完成任何事情,因为它位于错误的位置,并且在错误的时间被调用。如果
    新视图
    调用方执行了
    取消删除事件
    调用:

    var v = new myView({el: "#myView"});    
    v.undelegateEvents();
    new myView({el: "#myView"});
    

    然后它会在正确的时间和地点发生。当然,这意味着您的路由器需要跟踪当前视图,以便能够在正确的时间
    currentView.undelegateEvents()
    ;但是如果你这样做的话,你最好(依我看)采用我在答案顶部概述的方法。

    我不明白你试图通过两次初始化视图来做什么。如果要查看未删除的事件,请在单击“追加内部”按钮后将其移动,并实例化视图一次-单击只会触发一次,然后删除事件绑定。@bdc-我正在开发一个主干应用程序,通过在主干路由中实例化视图来切换视图,但这会导致在任何特定视图中委托的事件触发多次,具体取决于该视图的路由实例化该视图的次数(即,由用户在视图之间来回导航而不重新加载页面)。我想我可以通过在重新委派之前删除视图的任何委派事件来解决这个问题。另外,我想知道为什么我的示例会这样做-我认为undelegateEvents会做到这一点。在切换路由之前调用undelegateEvents,在initialize()之外应该可以。它在initialize中不起作用的原因是您正在实例化视图的两个独立实例。第二个实例未绑定到第一个实例中的事件。主干源:this.el.off('.delegateEvents'+this.cid)。this.cid对于您实例化的每个视图都是唯一的,即使DOM元素相同。请添加重现问题所需的代码。应该提供外部链接。我不明白初始化视图两次后你想做什么。如果要查看未删除的事件,请在单击“追加内部”按钮后将其移动,并实例化视图一次-单击只会触发一次,然后删除事件绑定。@bdc-我正在开发一个主干应用程序,通过在主干路由中实例化视图来切换视图,但这会导致在任何特定视图中委托的事件触发多次,具体取决于该视图的路由实例化该视图的次数(即,由用户在视图之间来回导航而不重新加载页面)。我想我可以通过在重新委派之前删除视图的任何委派事件来解决这个问题。另外,我想知道为什么我的例子