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();

这里是 http://jsbin.com/ciwunizuyi/edit?html,js,output

问题在于,在您的 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