使用一个DIV为多个骨干容器看待丢失事件绑定(using a single div as a con

2019-09-17 10:36发布

好了,我有一个导航和仪表板的概念。 在当我点击导航链接我的路由器,我打电话给我的仪表板视图设置活动选项卡。

例如:

<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标签加载预期。 但是如果我切换到一个标签,切换出来,然后再切换回它,在我看来,所有的事件都不再绑定。 点击,hoevering,没有内部foobars_view意见例如是可点击,hoverable等

在过去,我一直在为孩子的意见,像这样每一个的包装:

过去的解决方案,皮塔:

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的想法,始终保持开放......如果我不能做到这一点,我想对,就是那里的路上我只是上面显示的方法吗? 谢谢!

Answer 1:

当您使用.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

除去元素本身之前除去其他结构,例如从子元素数据和事件处理程序[为了避免内存泄漏]

所以,一旦你加入,也就是说, 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 (朋友),里面有他们的其他骨干网的观点,你必须调用delegateEvents上载意见一路下滑。 在这种情况下,某种bind_events方法上的意见才有意义:

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


文章来源: using a single div as a container for multiple backbone views losing event bindings