fgu*_*len 37 javascript-events backbone.js backbone-events
我有超级视图谁负责渲染子视图.当我重新渲染的超视图中的所有事件的子视图都将丢失.
这是一个例子:
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();
Run Code Online (Sandbox Code Playgroud)
当我点击click me div时,会触发事件.如果我composer.render()再次执行,所有内容看起来都很相似,但不会再触发click事件.
检查工作jsFiddle.
mu *_*ort 65
当你这样做:
this.$el.html( this.subView.render().el );
Run Code Online (Sandbox Code Playgroud)
你有效地这样说:
this.$el.empty();
this.$el.append( this.subView.render().el );
Run Code Online (Sandbox Code Playgroud)
并empty杀死内部事物的事件this.$el:
为了避免内存泄漏,jQuery在删除元素本身之前从子元素中删除了其他构造,如数据和事件处理程序.
因此,您将失去delegate绑定事件的调用,this.subView并且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;
}
Run Code Online (Sandbox Code Playgroud)
演示:http://jsfiddle.net/ambiguous/57maA/1/
或者像这样:
render: function(){
console.log( "Composer.render" );
this.$el.html( this.subView.render().el );
this.subView.delegateEvents();
return this;
}
Run Code Online (Sandbox Code Playgroud)
演示:http://jsfiddle.net/ambiguous/4qrRa/
或者你可以remove重新创建this.subView渲染时并以这种方式回避问题(但这可能会导致其他问题......).
JMM*_*JMM 11
这里有一个更简单的解决方案,它不会首先破坏事件注册:jQuery.detach().
this.subView.render().$el.detach().appendTo( this.$el );
Run Code Online (Sandbox Code Playgroud)
出于性能原因,这种变化可能更可取:
this.subView.$el.detach();
this.subView.render().$el.appendTo( this.$el );
// or
this.$el.append( this.subView.render().el );
Run Code Online (Sandbox Code Playgroud)
显然,这是一个与示例匹配的简化,其中子视图是父视图的唯一内容.如果确实如此,您可以重新渲染子视图.如果还有其他内容,您可以执行以下操作:
var children = array[];
this.$el.children().detach();
children.push( subView.render().el );
// ...
this.$el.append( children );
Run Code Online (Sandbox Code Playgroud)
要么
_( this.subViews ).each( function ( subView ) {
subView.$el.detach();
} );
// ...
Run Code Online (Sandbox Code Playgroud)
此外,在您的原始代码中,并在@ mu的答案中重复,传递一个DOM对象jQuery.html(),但该方法仅记录为接受HTML的字符串:
this.$el.html( this.subView.render().el );
Run Code Online (Sandbox Code Playgroud)
记录签名jQuery.html():
.html( htmlString )
Run Code Online (Sandbox Code Playgroud)
http://api.jquery.com/html/#html2
| 归档时间: |
|
| 查看次数: |
12232 次 |
| 最近记录: |