骨干:在重新渲染中丢失的事件
我有超级查看谁负责渲染子视图 。 当我重新渲染 超级查看 子 视图中的所有事件都丢失了。
这是一个例子:
var SubView = Backbone.View.extend({ events: { "click": "click" }, click: function(){ console.log( "click!" ); }, render: function(){ this.$el.html( "click me" ); return this; } }); var Composer = Backbone.View.extend({ initialize: function(){ this.subView = new SubView(); }, render: function(){ this.$el.html( this.subView.render().el ); } }); var composer = new Composer({el: $('#composer')}); composer.render();
当我点击我 div时触发事件。 如果我再次执行composer.render()
,所有东西都看起来很相似,但是click事件不再被触发。
检查工作jsFiddle 。
当你这样做:
this.$el.html( this.subView.render().el );
你有效地这样说:
this.$el.empty(); this.$el.append( this.subView.render().el );
empty
杀死在这里的一切事件this.$el
:
为了避免内存泄漏,jQuery在删除元素本身之前从子元素中删除其他构造,如数据和事件处理程序。
所以你失去了绑定this.subView
事件的delegate
调用和SubView#render
不会重新绑定它们。
你需要将this.subView.delegateEvents()
调用放到this.$el.html()
但是你需要在empty()
后面发生。 你可以这样做:
render: function(){ console.log( "Composer.render" ); this.$el.empty(); this.subView.delegateEvents(); this.$el.append( this.subView.render().el ); return this; }
演示: http : //jsfiddle.net/ambiguous/57maA/1/
或者像这样:
render: function(){ console.log( "Composer.render" ); this.$el.html( this.subView.render().el ); this.subView.delegateEvents(); return this; }
演示: http : //jsfiddle.net/ambiguous/4qrRa/
或者你可以remove
并重新创buildthis.subView
时,这样渲染和回避问题(但这可能会导致其他问题…)。
这里有一个更简单的解决scheme,它不会把事件注册放在第一位: jQuery.detach()
。
this.subView.render().$el.detach().appendTo( this.$el );
尽pipe这种变化可能是出于性能的原因:
this.subView.$el.detach(); this.subView.render().$el.appendTo( this.$el ); // or this.$el.append( this.subView.render().el );
显然,这是一个简单的匹配例子,其中子视图是父级的唯一内容。 如果真的如此,你可以重新渲染子视图。 如果有其他内容,你可以做一些事情:
var children = array[]; this.$el.children().detach(); children.push( subView.render().el ); // ... this.$el.append( children );
要么
_( this.subViews ).each( function ( subView ) { subView.$el.detach(); } ); // ...
另外,在您的原始代码中,并在@ mu的答案中重复,DOM对象被传递给jQuery.html()
,但该方法仅被logging为接受HTML的string:
this.$el.html( this.subView.render().el );
loggingjQuery.html()
签名:
.html( htmlString )
当使用$(el).empty()
它将删除所选元素中的所有子元素,并删除与所选元素( el
)内的任何(子元素)元素绑定的 所有 事件 (和数据)。
为了使事件绑定到 子元素 ,但仍然删除子元素,请使用:
$(el).children().detach();
而不是$(.el).empty();
这将允许您的视图顺利重新绑定事件仍然绑定和工作。
- Microsoft Office Excel不能访问文件'c:\ inetpub \ wwwroot \ Timesheet \ App_Data \ Template.xlsx'
- 重载运算符==与Equals()