单击删除按钮时删除相应的项目。 BackboneJs

时间:2016-02-11 17:32:18

标签: javascript jquery backbone.js

我目前正在学习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();

请帮助我或指出正确的方向,我将不胜感激。

3 个答案:

答案 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()?