Destroy()无法正常工作

时间:2015-07-02 22:28:06

标签: javascript jquery backbone.js

我正在使用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();

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

1 个答案:

答案 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