jquery – 使用单个div作为多个骨干视图的容器,从而丢失事件绑定

好的,所以我有一个导航和仪表板的概念.在我的路由器中单击导航链接时,我正在调用仪表板视图来设置活动选项卡.

例如:

NAV

<a href="#" class="dashabord_tab" id="widgets">Widgets</a>
<a href="#" class="dashabord_tab" id="Foobars">Foobars</a>

dashboard_container.jst.tpl

<div id="nav"></div>
<div id="current_tab"></div>

DASHABORDVIEW

DashboardView = Backbone.View.extend({
  template:JST.dashboard_container,render: function(){
    $(this.el).html(this.template());
  },activateWidgets: function(){ 
    if(!(this.widgets_view)){
      this.widgets_view = new WidgetsView();
      this.widgets_view.render();
    }
    $(this.el).find("#current_tab").html(this.widgets_view.el);
  },activateFoobars: function(){ 
    if(!(this.foobars_view)){
      this.foobars_view = new FooBarsView();
      this.foobars_view.render();
    }
    $(this.el).find("#current_tab").html(this.foobars_view.el);
  }
});

问题:

因此,当我第一次切换到widgets_tab或foobar_tab时,选项卡会按预期加载.但是,如果我切换到选项卡,切换它,然后切换回它,我视图中的所有事件都不再绑定.点击,欢迎,foobars_view中的任何视图都不是可点击的,可以浏览的等等.

在过去,我一直在为每个子视图创建一个包装器,如下所示:

过去的解决方案,皮塔饼:

activateFoobars: function(){ 
    $('.tab_wrapper').hide();
    if($(this.el).find("#foobars_wrapper").length < 1){
      $(this.el).append("<div class='tab_wrapper' id='foobars_wrapper'></div>");
      this.foobars_view = new FooBarsView();
      $(this.el).find("#foobars_wrapper").html(this.foobars_view.render().el);
    }
  $('#foobars_wrapper').show();
  }

我宁愿不按照上面所示的方式去做,而且我真的很想把视图的el放在一个始终保持开放的active_tab div中…如果我不能按照我喜欢的方式去做to,有没有替代我上面展示的方式?谢谢!

解决方法

使用 .html(dom_object)时:

$(this.el).find("#current_tab").html(this.widgets_view.el);

你实际上是这样做的:

$(this.el).find('#current_tab').empty().append(this.widgets_view.el);

empty

removes other constructs such as data and event handlers from the child elements before removing the elements themselves [To avoid memory leaks]

所以,一旦你将widgets_view添加到#current_tab然后再添加.html(this.foobars_view.el),widgets_view.el上的事件就会消失.您的.html调用第一次运行正常,因为#current_tab中没有任何内容,因此没有任何事件可以取消绑定.

您可以通过在混合中添加简单的delegateEvents调用来重新绑定事件来使用“重用视图”方法:

activateWidgets: function(){ 
  if(!(this.widgets_view)){
    this.widgets_view = new WidgetsView();
    this.widgets_view.render();
  }
  $(this.el).find("#current_tab").html(this.widgets_view.el);
  this.widgets_view.delegateEvents(); // <--------------- you need this
}

当我在这里时,您可以使用this.$('#current_tab')而不是$(this.el).find(‘#current_tab’)和this.$el而不是$(this.el).

演示:http://jsfiddle.net/ambiguous/75KuW/1/

请注意,上面的切换标签会保留< input type =“text”>的内容.元素.如果您不需要这种行为,那么您可能最好根据需要删除和实例化视图,而不是保留所有视图并将它们交换进去.

此外,如果您的WidgetsView(和朋友)在其中包含其他Backbone视图,则您必须在所包含的视图上一直调用delegateEvents.在这种情况下,视图上的某种bind_events方法是有意义的:

this.widgets_view.rebind_events(); // delegateEvents() all the way down this view subtree

相关文章

1.第一步 设置响应头 header(&#39;Access-Control-Allow...
$.inArray()方法介绍 $.inArray()函数用于在数组中搜索指定的...
jquery.serializejson.min.js的妙用 关于这个jquery.seriali...
JS 将form表单数据快速转化为object对象(json对象) jaymou...
jQuery插件之jquery.spinner数字智能增减插件 参考地址:http...