Destroy() 无法正常工作
Destroy() doesn't work properly
我正在使用 Backbone.js
编写基本的待办事项列表。每个输入都作为模型添加到集合中。在收集和渲染新添加的模型时监听 'add'(将带有 'task' 的 li 附加到 ul)。然后通过双击项目我检索它的 html()
并在一个循环中将它与模型中的相应属性进行比较。当它捕捉到正确的模型时 - 销毁模型(应该相应地从集合中删除)。但是控制台出现了一些问题,它说
Uncaught TypeError: Cannot read property 'toJSON' of undefined
并添加一些错误效果(并非每次都可以通过第一个 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();
问题在于,在您的 destroy
方法中,您通过比较模型的 task
属性 找到要销毁的模型。如果您有多个具有相同 task
属性 的模型,您将收到错误消息。发生实际错误是因为您在迭代集合时从集合中删除项目。
您可以使用 Backbone 给出所有模型的 cid
(客户端 ID)属性,而不是比较 task
属性。一种方法是:
渲染 ItemView
时,使用 jQuery 的 data
方法将 cid
与视图元素一起存储(或者,use a custom data attribute)
this.$el.data('cid', this.model.cid);
在destroy
函数中,从视图元素中获取cid
属性,并用它在集合中找到合适的模型(你可以在此处使用集合的 get
方法):
destroy: function (e) {
var id = $(e.target).data('cid');
var model = this.collection.get(id);
model.destroy();
e.target.remove();
},
向 DOM 元素添加唯一属性只是解决此问题的一种方法。一种更好的替代方法是从 ItemView
class 本身监听双击事件。这样,您将始终引用 this.model
.
编辑:这显示了上面的代码:http://jsbin.com/nijikidewe/edit?js,output
我正在使用 Backbone.js
编写基本的待办事项列表。每个输入都作为模型添加到集合中。在收集和渲染新添加的模型时监听 'add'(将带有 'task' 的 li 附加到 ul)。然后通过双击项目我检索它的 html()
并在一个循环中将它与模型中的相应属性进行比较。当它捕捉到正确的模型时 - 销毁模型(应该相应地从集合中删除)。但是控制台出现了一些问题,它说
Uncaught TypeError: Cannot read property 'toJSON' of undefined
并添加一些错误效果(并非每次都可以通过第一个 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();
问题在于,在您的 destroy
方法中,您通过比较模型的 task
属性 找到要销毁的模型。如果您有多个具有相同 task
属性 的模型,您将收到错误消息。发生实际错误是因为您在迭代集合时从集合中删除项目。
您可以使用 Backbone 给出所有模型的 cid
(客户端 ID)属性,而不是比较 task
属性。一种方法是:
渲染
ItemView
时,使用 jQuery 的data
方法将cid
与视图元素一起存储(或者,use a custom data attribute)this.$el.data('cid', this.model.cid);
在
destroy
函数中,从视图元素中获取cid
属性,并用它在集合中找到合适的模型(你可以在此处使用集合的get
方法):destroy: function (e) { var id = $(e.target).data('cid'); var model = this.collection.get(id); model.destroy(); e.target.remove(); },
向 DOM 元素添加唯一属性只是解决此问题的一种方法。一种更好的替代方法是从 ItemView
class 本身监听双击事件。这样,您将始终引用 this.model
.
编辑:这显示了上面的代码:http://jsbin.com/nijikidewe/edit?js,output