我在骨干网中创建了一个众所周知的待办事项列表应用,但有一个功能无效,mycollection.add()
方法。
使用todoItems.remove(todoItem.at(0))
删除项目时,一切正常。
我遇到的问题是添加新项目时:
var newItem = new todoItem({ description: "cereal killer", status: "complete" });
todoItems.add(newItem)
- >这不会将它添加到集合中,长度仍然相同。
我可以添加新项目的唯一方法是先删除一项,然后添加项目,但只能使用一项。
有任何线索吗?
这是主要代码:
app.js
var TodoItem = Backbone.Model.extend({
defaults: {
description: "Pick up milk",
status: "incomplete",
id: 1
},
toggleStatus: function(){
if(this.get('status') === 'incomplete'){
this.set({'status': 'complete'});
} else {
this.set({'status': 'incomplete'});
}
this.save();
}
});
var TodoItems = Backbone.Collection.extend({
model: TodoItem,
localStorage: new Backbone.LocalStorage("choose-some-identifier"),
initialize: function () {
this.on('remove', this.hideModel, this);
},
hideModel: function (model) {
model.trigger('hide');
}
});
var TodosView = Backbone.View.extend({
initialize: function () {
this.collection.on('add', this.addOne, this);
this.collection.on('reset', this.addAll, this);
},
render: function() {
this.addAll();
// this.collection.forEach(this.addOne, this);
return this;
},
addOne: function (todoItem) {
var todoView = new TodoView({ model: todoItem });
this.$el.append(todoView.render().$el);
},
addAll: function () {
this.collection.forEach(this.addOne, this);
}
});
var TodoView = Backbone.View.extend({
tagName: 'article',
id: 'todo-view',
className: 'todo',
template: _.template('<h3 class="<%= status %>">' +
'<input type=checkbox ' +
'<% if (status === "complete") print("checked") %> />' +
'<%= description %></h3>'),
events: {
"change input": "toggleStatus"
},
toggleStatus: function () {
this.model.toggleStatus();
},
remove: function(){
this.$el.remove();
},
initialize: function(){
this.render();
this.model.on('change', this.render, this);
this.model.on('destroy', this.remove, this);
this.model.on('hide', this.remove, this);
},
render: function () {
var attributes = this.model.toJSON();
this.$el.html(this.template(attributes));
return this;
}
});
var todoItems = new TodoItems([
{
description: 'Jeffrey Way',
status: "incomplete"
},
{
description: 'John Doe',
status: "incomplete"
},
{
description: 'Sally Doe',
status: "incomplete"
}
]);
var todosView = new TodosView({ collection: todoItems});
$(document.body).append(todosView.render().el);
答案 0 :(得分:2)
问题在于:
defaults: {
description: "Pick up milk",
status: "incomplete",
id: 1
}
您已将id
设为默认值。一个id应该是唯一的,你试图添加另一个模型而不指定一个新的id,所以Backone有用地注意到你已经有一个带有该id的模型,所以它不会添加它。
解决方案:您不应该设置默认ID,在本地创建模型时,正常流程是:
- 创建没有id的模型
- 在某些时候.save
它
- 服务器响应所有属性+保存后的ID
当然,获取已存在于服务器上的模型应该已经有了id。
PS你不需要为单个集合(或获取)制作哈希:
this.set('status', 'complete');
PPS在您看来,最好使用listenTo
:
this.listenTo(this.collection, 'add', ...);
这可以防止在某些情况下出现memleaks,并且可以更轻松地批量停止收听事件。