问题以下列方式复制:
每当我向后导航时,模型都不会被渲染。我想那是因为这个事件没有被触发:
this.listenTo(this.collection, 'add', this.addOne);
this.listenTo(this.collection, 'reset', this.addAll);
这是我的路由器:
routes: {
'' : 'home',
'home' : 'home',
'departments' : 'departments',
...
},
home: function(){
var view = new app.HomeView();
this.showView(view);
},
departments: function(){
var view = new app.DepartmentsView();
this.showView(view);
},
showView: function(view){
if (this.currentView){
this.currentView.clean();
}
this.currentView = view;
this.currentView.render()
$('#container').html(this.currentView.el);
}
这是我干净的方法:
Backbone.View.prototype.clean = function () {
this.remove();
this.unbind();
_.each(this.subViews, function(subView){
subView.clean();
if(subView.onClose){ subView.onClose() }
});
};
这是子视图上的onClose方法:
onClose: function(){
this.model.off('change',this.render);
this.model.off('destroy',this.remove);
console.log('unbinding');
}
我将所有子视图保存在数组中,然后在导航时关闭。我真的没有找出这种问题的根本原因。
我非常绝望,因为我已尝试过Derick Bailey的所有帖子并通过Backbone的文档,并且无法解决这个问题。
------ -------- EDIT 该视图的组成如下:
<tr>
这是我的回购,如果你想看看。实际上再现一些最小的东西是在问题中发布的大量代码。 REPO
我很感激你的帮助。
答案 0 :(得分:1)
这是我怀疑问题所在。您的Departments
集合仅实例化一次app.Departments = new DepartmentList();
。然后在DepartmentsView
初始化函数中,指定this.collection = app.Departments;
这意味着第二次转到DepartmentsView
时,您将其集合分配给已有模型的现有集合。当您调用fetch()
时,Backbone会检测到没有新模型(因为您已经在集合中有模型),因此不会触发添加事件。
您可以做的一件事是使用重置fetch({reset:true})
来调用fetch。然后,当获取成功时,它将清除现有模型并重新添加它们,并触发重置。
由于您已拥有模型,因此重置有点浪费。另一个解决方案是检查集合中是否包含init函数中的任何模型,如果它然后再渲染它们。像这样的东西
initialize: function(){
this.collection = app.Departments;
this.subViews = [];
if(this.collection.size() > 0)
this.collection.each(this.addOne, this);
this.listenTo(this.collection, 'add', this.addOne);
this.listenTo(this.collection, 'reset', this.addAll);
this.collection.fetch();
},
然后,fetch将添加它在获取成功时找到的任何新模型。
编辑:不是最干净的解决方案,但它应该有效。
initialize: function(){
this.collection = app.Departments;
this.subViews = [];
if(this.collection.size() > 0)
this.preExisting = true;
this.listenTo(this.collection, 'add', this.addOne);
this.listenTo(this.collection, 'reset', this.addAll);
this.collection.fetch();
},
render: function(){
this.$el.html( this.template({title: 'Departamentos',header_fields: this.tableHeader}) );
this.$tbody = this.$('#rows');
if(this.preExisting)
this.collection.each(this.addOne, this);
return this;
},