我正在使用Backbone.js
编写基本待办事项列表。每个输入作为模型添加到集合中。倾听'添加'关于收集和渲染新添加的模型(将li附加到'任务'到ul)。然后双击项目I,检索它的html()
并在循环中将其与模型中的相应属性进行比较。当它捕获正确的模型 - 销毁模型(应相应地从集合中删除)。但是在控制台中出现了一些问题,它说
未捕获的TypeError:无法读取属性' toJSON'未定义的
并添加一些buggy效果(不是每次都可以通过第一个dblckick删除项目)。如果有人能指出问题,将不胜感激! 这里的代码
var Model = Backbone.Model.extend({
default: {
task: '',
completed: false
}
});
var Collection = Backbone.Collection.extend({
model: Model
});
var ItemView = Backbone.View.extend({
tagName: 'li',
render: function () {
this.$el.html(this.model.toJSON().task);
return this;
}
});
var TodoView = Backbone.View.extend({
el: '#todo',
initialize: function () {
this.collection = new Collection();
this.collection.on('add', this.render, this);
},
events: {
'click .add': 'add',
'dblclick li': 'destroy',
'keydown': 'keyEvent'
},
add: function () {
this.collection.add(new Model({ //adding input as an model to collection
task: this.$el.find('#todo').val(),
completed: false
}));
this.$el.find('#todo').val(''); //clearing input field
this.$el.find('#todo').focus(); //focusing input after adding task
},
keyEvent: function (e) {
if (e.which === 13) {
this.add();
}
},
destroy: function (e) {
// console.log(this.collection.toJSON());
this.collection.each(function (model) {
if ($(e.target).html() === model.toJSON().task) {
model.destroy();
}
});
e.target.remove();
// console.log(this.collection.toJSON());
},
render: function (newModel) {
var self = this,
todoView;
todoView = new ItemView({
model: newModel
});
self.$el.find('.list').append(todoView.render().el);
return this;
}
});
var trigger = new TodoView();
答案 0 :(得分:1)
问题在于,在destroy
方法中,通过比较模型的task
属性,可以找到要销毁的模型。如果您有多个具有相同task
属性的模型,则会收到错误。发生实际错误是因为您在迭代它时从集合中删除项目。
您可以使用Backbone为所有模型提供的task
(客户端ID)属性,而不是比较cid
属性。一种方法是:
渲染ItemView
时,使用jQuery的data
方法将cid
与视图元素一起存储(或者,use a custom data attribute)
this.$el.data('cid', this.model.cid);
在destroy
函数中,从view元素中获取cid
属性,并使用它在集合中查找正确的模型(您可以使用集合的get
这里的方法):
destroy: function (e) {
var id = $(e.target).data('cid');
var model = this.collection.get(id);
model.destroy();
e.target.remove();
},
向DOM元素添加唯一属性只是解决此问题的一种方法。一个更好的替代方案是从ItemView
类本身监听双击事件。这样,您总是会引用this.model
。
编辑:这会显示上面的代码:http://jsbin.com/nijikidewe/edit?js,output