2013-05-13 4 views
0

Я делаю пример приложения, аналогичного Backbone-Todo. Но когда я вызываю уничтожение в коллекции, он дает ошибку:Calling destroy on collection

Uncaught TypeError: Cannot read property 'destroy' of undefined

Как решить эту проблему. Пожалуйста, предложите.

Ниже мой метод Код:

$(function(){ 

var Todo = Backbone.Model.extend({ 

defaults: function() { 
    return { 
    title: "empty todo...", 
    order: Todos.nextOrder(), 
    done: false 
    }; 
} 

}); 


var TodoList = Backbone.Collection.extend({ 

    model : Todo, 

    localStorage: new Backbone.LocalStorage("todos-backbone"), 

    done: function() { 
    return this.where({done: true}); 
    }, 

    remaining: function() { 
    return this.without.apply(this, this.done()); 
    }, 

    nextOrder: function() { 
    if (!this.length) return 1; 
    return this.last().get('order') + 1; 
    }, 

    comparator: 'order' 
}); 

var TodoView = Backbone.View.extend({ 

    tagName: "li", 

    template: _.template($('#item-template').html()), 

    events: { 
    "click a.destroy" : "clear" 
    }, 

    initialize: function() { 
    this.listenTo(this.model, 'destroy', this.remove); 
    }, 

    render: function() { 
    this.$el.html(this.template(this.model.toJSON())); 
    return this; 
    }, 

    clear: function(){ 
    this.model.destroy(); 
    } 
}); 

var AppView = Backbone.View.extend({ 

    el: $("#todoapp"), 

    statsTemplate: _.template($('#stats-template').html()), 

    events: { 
    "keypress #new-todo": "createOnEnter", 
    "click #remove-all": "clearCompleted" 
    }, 

    initialize: function() { 
    this.input = this.$("#new-todo"); 
    this.main = $('#main'); 
    this.footer = this.$('footer'); 

    this.listenTo(Todos, 'add', this.addOne); 
    this.listenTo(Todos, 'all', this.render); 

    Todos.fetch(); 
    }, 

    render: function() { 
    var done = Todos.done().length; 
    var remaining = Todos.remaining().length; 

    if (Todos.length) { 
     this.main.show(); 
     this.footer.show(); 
     this.footer.html(this.statsTemplate({done: done, remaining: remaining})); 
    } else { 
     this.main.hide(); 
     this.footer.hide(); 
    } 
    }, 

    createOnEnter: function(e){ 
    if(e.keyCode != 13) return; 
    if (!this.input.val()) return; 
    Todos.create({ 
     title: this.input.val() 
    }) 
    this.input.val('');   
    }, 

    addOne: function(todo){ 
    var view = new TodoView({model: todo}); 
    this.$("#todo-list").append(view.render().el); 
    }, 

    clearCompleted: function(){ 
    _.invoke(Todos, 'destroy'); 
    return false; 
    } 

});

+0

Ваш вопрос может потребовать больше контекста. Исходный код вызывает метод «Todos.done()», который отменяет вызов, когда доступен целевой объект (в хорошем случае). –

+0

Привет, Эрик, Я представил свой код приложения. Не могли бы вы сейчас это понять. Спасибо – KSL

ответ

0

для этого ответа Предполагаю, что Todos является примером TodoList. Я также предполагаю, что ваша ошибка вызывается с помощью этой функции в вашем AppView

clearCompleted: function(){ 
    _.invoke(Todos, 'destroy'); 
    return false; 
} 

В там вы пытаетесь лечить ваш Backbone.js Collection экземпляра как то, что это, коллекция, например, список. Но коллекции Backbone - это не просто списки, они являются объектами, у которых есть свойство models, которое представляет собой список, содержащий все ваши модели. Поэтому попытка использования подчеркивания invoke(which works on lists) на объекте неизбежно вызывает ошибки.

Но не волнуйтесь. Магистраль аккуратно реализует многие методы подчёркивания для своих Model и Collection, including invoke. Это означает, что вы можете вызвать уничтожение для каждой модели в такой коллекции

SomeCollection.invoke('destroy'); 

Надеюсь, это поможет!

+0

Да, хорошо, спасибо! – KSL

Смежные вопросы