我目前正在学习BackboneJs并试图了解Backbone如何处理事件。我有一个简单的项目列表,每个项目旁边都有一个delete
按钮。我试图弄清楚为什么在控制台中注册了点击事件(删除按钮)但该项目未被删除。这就是我所拥有的:
var Vehicle = Backbone.Model.extend();
var Vehicles = Backbone.Collection.extend({
model: Vehicle
});
/*************
single view
**************/
var VehicleView = Backbone.View.extend({
tagName: 'li',
className: 'vehicle',
render: function() {
this.$el.html(this.model.get("title") + " Registration Number is: " + this.model.get("regiNum") + " <button class='delete-btn'>Delete</button>");
this.$el.attr("id", this.model.id);
return this;
}
});
/*************
Collection View
*************/
var VehiclesView = Backbone.View.extend({
tagName: "ul",
initialize: function() {
this.model.on('remove', this.vehicleRemove, this);
},
events: {
"click .delete-btn": "vehicleRemove"
},
vehicleRemove: function(vehicle) {
this.$("li#" + vehicle.id).remove() // this is not working. the item is not being removed
console.log('Delete button clicked') // this is registered in the console log
},
render: function() {
var self = this;
this.model.each(function(vehicle) {
var vehicleView = new VehicleView({
model: vehicle
});
self.$el.append(vehicleView.render().$el);
})
}
});
var vehicles = new Vehicles([
new Vehicle({
id: 1,
title: "Toyota",
regiNum: "453454624"
}),
new Vehicle({
id: 2,
title: "Honda",
regiNum: "daf4526"
}),
new Vehicle({
id: 3,
title: "Audi",
regiNum: "jlkjfa34"
})
])
var vehiclesView = new VehiclesView({
el: "#container",
model: vehicles
});
vehiclesView.render();
请帮助我或指出正确的方向,我将不胜感激。
答案 0 :(得分:1)
您可能希望在按钮上使用的有用的属性是data-id
。将此值设置为模型ID可以让您更清晰地选择正确的模型进行删除。新的按钮html现在是:
"<button class='delete-btn' data-id=" + this.model.get('id') + ">Delete</button>"
有这样的按钮,新的点击事件可以这样解雇:
vehicleRemove: function(e) {
e.preventDefault(); //Good practice for button clicks
var id = $(e.currentTarget).data('id'); //Id of model clicked
//Only one of these next two lines needs to be used
this.collection.remove(id); //If not persisting to server
this.collection.remove(id).destroy() //If persisting to server
},
此外,当您实例化VehicleView时,由于您正在向其传递名为vehicles
的集合,因此该属性应该真正称为collection
,而不是model
。名为model
的属性通常用于单个模型视图,或表示model
collection
代表的VehiclesView
。需要在model
内进行适当的更改,即用collection
替换单词libfoo.a
的每个实例。
答案 1 :(得分:1)
由于您有项目视图,因此最好为其提供自行删除功能。这样,您就不必破解从DOM中读取内容的方式,以便根据单击的项目视图元素查找相关模型。
此外,您应该使用Backbone.View的remove()
方法而不是jQuery remove()
方法,因为它可以安全地删除在视图上注册的骨干事件,以及调用jQuery {{1从DOM中删除元素。
您可以调用remove()
来表示持久层,以删除模型并将其从集合中删除。由于您在此示例中没有持久层,因此我在项目视图的模型上触发自定义事件,该模型在集合中处理以从中移除模型(模型事件传播到它的集合)。
无需自己手动初始化集合中的模型,骨干自动执行,这就是集合model.destroy()
属性的用途。
您应该使用某种模板引擎,而不是在视图中进行字符串操作以进行渲染,无论如何都可以使用model
。
此外,正如dskoda1已经提到的那样,你不应该使用_.template()
选项传递Backbone.Collection,模型和集合是Backbone.view将检测到的两个选项。即使它没有伤害,它仍然非常令人困惑。
model
var Vehicle = Backbone.Model.extend();
var Vehicles = Backbone.Collection.extend({
model: Vehicle,
initialize: function() {
this.on('delete', this.remove);
}
});
var VehicleView = Backbone.View.extend({
tagName: 'li',
className: 'vehicle',
template: _.template($('#vehicle-template').html()),
events: {
"click .delete-btn": "vehicleRemove"
},
initialize: function() {
this.render();
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
vehicleRemove: function(vehicle) {
this.remove();
//this.model.destroy(); /* The collection should have a url */
this.model.trigger('delete', this.model);
},
});
var VehiclesView = Backbone.View.extend({
tagName: "ul",
initialize: function() {
this.render();
},
render: function() {
this.collection.each(function(vehicle) {
var vehicleView = new VehicleView({
model: vehicle
});
this.$el.append(vehicleView.$el);
}, this)
}
});
var vehicles = new Vehicles([{
id: 1,
title: "Toyota",
regiNum: "453454624"
}, {
id: 2,
title: "Honda",
regiNum: "daf4526"
}, {
id: 3,
title: "Audi",
regiNum: "jlkjfa34"
}]);
var vehiclesView = new VehiclesView({
el: "#container",
collection: vehicles
});
答案 2 :(得分:-1)
this.remove()
?
此时,Backbone已经知道您尝试删除哪个模型,因此无需指定jQuery选择器。
当然,.remove()只会从DOM中删除该元素。您是否正在寻找将向服务器发送DELETE命令的model.destroy()?