Jquery 使用单个div作为多个主干视图的容器会丢失事件绑定
好的,我有一个导航和仪表板的概念。在我的路由器中,当我单击导航链接时,我正在调用我的仪表板视图来设置活动选项卡 例如: 导航 问题是: 因此,当我第一次切换到widgets_选项卡或foobar_选项卡时,选项卡将按预期加载。但是,如果切换到某个选项卡,将其切换出,然后切换回该选项卡,则视图中的所有事件都不再绑定。例如,在foobars\u视图中,没有一个视图是可点击、可悬停等的 过去,我一直在为每个子视图制作包装,如下所示: 过去的解决方案,pita:Jquery 使用单个div作为多个主干视图的容器会丢失事件绑定,jquery,backbone.js,backbone-events,Jquery,Backbone.js,Backbone Events,好的,我有一个导航和仪表板的概念。在我的路由器中,当我单击导航链接时,我正在调用我的仪表板视图来设置活动选项卡 例如: 导航 问题是: 因此,当我第一次切换到widgets_选项卡或foobar_选项卡时,选项卡将按预期加载。但是,如果切换到某个选项卡,将其切换出,然后切换回该选项卡,则视图中的所有事件都不再绑定。例如,在foobars\u视图中,没有一个视图是可点击、可悬停等的 过去,我一直在为每个子视图制作包装,如下所示: 过去的解决方案,pita: activateFobors:funct
activateFobors:function(){
$('.tab_包装器').hide();
if($(this.el).find(“#foobars_wrapper”).length<1){
$(this.el)。追加(“”);
this.foobars_view=new FooBarsView();
$(this.el).find(“#foobars_wrapper”).html(this.foobars_view.render().el);
}
$(“#foobars_wrapper”).show();
}
我不想像上面那样做,我真的很喜欢把视图的el放在一个始终保持打开的活动选项卡div中的想法。。。如果我不能按照我喜欢的方式去做,有没有其他方法可以替代我刚才展示的方式?谢谢 使用时:
实际上,您正在这样做:
$(this.el).find('#current_tab').empty().append(this.widgets_view.el);
以及:
在移除元素本身之前,从子元素中移除其他构造(如数据和事件处理程序)[以避免内存泄漏]
因此,一旦您将widgets\u view
添加到#current\u选项卡
,然后添加.html(this.foobars\u view.el)
,那么widgets\u view.el上的事件就消失了。您的.html
调用第一次就可以正常工作,因为#current_选项卡中没有任何内容,因此没有任何要解除绑定的事件
您可以使用“重用视图”方法,将简单调用添加到混合中以重新绑定事件:
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
}
这在JSFIDLE示例中非常有效。。。由于某些原因,它在我的应用程序中不起作用。我应该注意到widgetsview和foobarview都有自己的子视图。这有什么区别吗?@jdkealy:您可能需要一直delegateEvents
,因为empty
调用将终止所有事件绑定。在视图上使用一种方法(比如重新绑定所有事件
)来执行必要的delegateEvents
,将有助于正确封装内容。啊,我现在明白了,当我放置在一个简单视图中时,它非常有效。。。是的,我的观点太深奥了,我认为不应该一直把委派事件称为一系列事件。这是很好的了解,以供将来参考,但我想我会使用显示/隐藏或偏移方法。谢谢
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);
}
});
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();
}
$(this.el).find("#current_tab").html(this.widgets_view.el);
$(this.el).find('#current_tab').empty().append(this.widgets_view.el);
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.widgets_view.rebind_events(); // delegateEvents() all the way down this view subtree