【发布时间】:2014-09-18 14:53:52
【问题描述】:
我对骨干很陌生,我试图了解僵尸视图的来龙去脉。
僵尸是,根据这个article:
当我们通过事件将对象绑定在一起但我们不去解绑它们时。只要这些对象绑定在一起,并且在我们的应用程序代码中至少有一个引用,它们就不会被清理或垃圾收集。由此产生的内存泄漏就像电影中的僵尸——躲在黑暗的角落里,等着跳出来吃我们的午餐。
上面提到的文章建议创建一个对象来管理视图之间的转换,然后实现一个关闭函数来删除和取消绑定视图。
话虽如此,根据情况,从哪里调用关闭函数?
我在父视图的初始化块中添加了一个属性来跟踪子视图。这样我就可以在用新的替换它之前调用 .remove() 。这是好的做法还是有更好的方法?
我也不明白为什么要定义el然后用渲染
this.$el.html(this.template(this.model.attributes));
不允许我在视图按预期工作时解除绑定
$('#sportsManDetails').html(this.$el.html(this.template(this.model.attributes)));
举个例子,我刚刚创建了一个简单的应用程序,它显示运动员姓名列表,并在单击姓名时显示更多详细信息。
这是代码和有效的fiddle:
html
<script id="nameListTemplate" type="text/template">
<%= first %> <%= last %>
</script>
<script id="sportsManDetailsTemplate" type="text/template">
<ul>
<li><%= first %></li>
<li><%= last %></li>
<li><%= age %></li>
<li><%= sport %></li>
<li><%= category %></li>
</ul>
<button class="test">Test</button>
</script>
<div id="sportsMenName"></div>
<div id="sportsManDetails"></div>
JS
模型和集合
var app = app || {};
app.SportsManModel = Backbone.Model.extend({});
app.SportsMenCollection = Backbone.Collection.extend({
model: app.SportsManModel
});
名称视图
app.NameView = Backbone.View.extend({
tagName: 'li',
className: 'sportsMan',
template: _.template($('#nameListTemplate').html()),
initialize: function(){
this.sportsManDetailsView;
},
events: {
'click': 'showSportsManDetails'
},
showSportsManDetails: function(e){
if (typeof this.sportsManDetailsView !== 'undefined'){
this.sportsManDetailsView.remove();
}
this.sportsManDetailsView = new app.SportsManDetailsView({
model: this.model
})
},
render: function(){
this.$el.append(this.template(this.model.attributes));
return this;
}
});
NameListView
app.NameListView = Backbone.View.extend({
el: '#sportsMenName',
initialize: function(sportsMen){
this.collection = new app.SportsMenCollection(sportsMen);
this.render();
},
render: function(){
this.collection.each(function(sportsMen){
this.renderContact(sportsMen);
}, this);
},
renderContact: function(sportsMen){
var nameView = new app.NameView({
model: sportsMen
});
this.$el.append(nameView.render().el);
}
});
SportsManDetailsView
app.SportsManDetailsView = Backbone.View.extend({
// doesn't work if I use el in conjunction with
// this.$el.html(this.template(this.model.attributes));
// el: '#sportsManDetails',
template: _.template($('#sportsManDetailsTemplate').html()),
initialize: function(){
this.render();
},
events: {
'click .test': 'test'
},
test: function(){
alert('test');
},
render: function(){
// that does not work
//this.$el.html(this.template(this.model.attributes));
// is this good practice?
$('#sportsManDetails').html(this.$el.html(this.template(this.model.attributes)));
}
});
app.js
var sportsMen = [
{first: 'Quentin', last: 'Tarant', age: '34', sport: 'bike', category: '- 90kg'},
{first: 'Aymeric', last: 'McArthur', age: '54', sport: 'jetski', category: '200HP'},
{first: 'Peter', last: 'TheFat', age: '45', sport: 'curling', category: 'dunno'},
{first: 'Charles', last: 'Martel', age: '21', sport: 'Moto', category: 'MX 250cc'},
];
$(function(){
new app.NameListView(sportsMen);
});
【问题讨论】: