未捕获的TypeError:无法在'中使用'运营商搜索' model'在未定义

时间:2015-09-27 09:13:31

标签: javascript backbone.js underscore.js

我从在线图书&骨干基础知识中学习Backbone.js, 在尝试示例时,我在控制台中出现了与underscore.js相关的错误:

Uncaught TypeError: Cannot use 'in' operator to search for 'model' in undefined

我搜索了SO上的错误我发现这个错误的原因是我不应该在初始化时将字符串传递给我的模型。但我没有。

这是我的项目,我的模型:

// models/todo.js    
var app = app || {};

app.Todo = Backbone.Model.extend({

    defaults: {
        title: '',
        completed: false
    },

    toggle: function() {
        this.save({
            completed: !this.get('completed')
        });
    }
});

我的收藏:

// collections/todos.js
var app = app || {};

var TodoList = Backbone.Collection.extend({
    model: app.Todo,

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

    completed: function() {
        return this.filter( function( todo ) {
            return todo.get('completed');
        });
    },

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

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

    comperator: function(todo) {
        return todo.get('order');
    }
});

app.Todos = new TodoList();

我有两种观点。

// views/todos.js
var app = app || {};


app.TodoView = Backbone.View.extend({
    tagName: 'li',

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

    events: {
        'dbclick label': 'edit',
        'keypress .edit': 'updateOnEnter',
        'blur .edit': 'close'
    },

    initialize: function() {
        this.listenTo(this.model, 'change', this.render);
    },

    render: function() {
        this.$el.html( this.template(this.model.attributes) );
        this.$input = this.$('.edit');
        return this;
    },

    edit: function() {
        this.$el.addClass('editing');
        this.$input.focus();
    },

    close: function() {
        var value = this.$input.val().trim();

        if( value ) {
            this.model.save({ title: value });
        }

        this.$el.removeClass('editing');
    },

    updateOnEnter: function(e) {
        if (e.which === ENTER_KEY) {
            this.close();
        }
    }
});

// views/app.js
// maybe i should rename this file to appView.js
var app = app || {};

app.AppView = Backbone.View.extend({
    el: '.todoapp',

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

    events: {
        'keypress .new-todo': 'createOnEnter',
        'click .clear-completed': 'clearCompleted',
        'click .toggle-all': 'toggleAllComplete'
    },

    initialize: function() {
        this.allCheckbox = this.$('.toggle-all')[0];
        this.$input = this.$('.new-todo');
        this.$footer = this.$('.footer');
        this.$main = this.$('.main');

        this.listenTo(app.Todos, 'add', this.addOne);
        this.listenTo(app.Todos, 'reset', this.addAll);

        this.listenTo(app.Todos, 'change:completed', this.filterOne);
        this.listenTo(app.Todos, 'filter', this.filterAll);
        this.listenTo(app.Todos, 'all', this.render);

        app.Todos.fetch();
    },

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

        if(app.Todos.length) {
            this.$main.show();
            this.$footer.show();

            this.$footer.html(this.statsTemplate({
                completed: completed,
                remaining: remaining
            }));

            this.$('#filters li a')
                .removeClass('selected')
                .filter('[href="#/' + (app.TodoFilter || '' ) + '"]')
                .addClass('selected');
        } else {
            this.$main.hide();
            this.$footer.hide();
        }

        this.allCheckbox.checked = !remaining;
    },

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

    addAll: function() {
        this.$('.todo-list').html('');
        app.Todos.each(this.addOne, this);
    },

    filterOne: function(todo) {
        todo.trigger('visible');
    },

    filterAll: function() {
        app.Todos.each(this.filterOne, this);
    },

    newAttributes: function() {
        return {
            title: this.$input.val().trim(),
            order: app.Todos.nextOrder(),
            completed: false
        };
    },

    createOnEnter: function( event ) {
        if( event.which !== ENTER_KEY || !this.$input.val().trim() ) {
            return;
        }

        app.Todos.create( this.newAttributes() );
        this.$input.val('');
    },

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

    toggleAllComplete: function() {
        var completed = this.allCheckbox.checked;

        app.Todos.each(function(todo) {
            todo.save({
                'completed': completed
            });
        });
    }

});

app.js:

// js/app.js

var app = app || {};
var ENTER_KEY = 13;
var ESC_KEY = 27;

    $(function() {

        new app.AppView();

    });

当发生这样的错误时,我应该看哪里? 谢谢你的时间......

编辑:
  当我加载页面而不做任何进一步的操作时,会发生错误   文件的顺序是:

<script src="js/models/todo.js"></script>
<script src="js/collections/todos.js"></script>
<script src="js/views/todos.js"></script>
<script src="js/views/app.js"></script>
<script src="js/routers/router.js"></script>
<script src="js/app.js"></script>

整个错误消息:

Uncaught TypeError: Cannot use 'in' operator to search for 'model' in undefined
   (anonymous function) @   underscore.js:5
   j.each.j.forEach @   underscore.js:5
   j.pick   @   underscore.js:5
   Backbone.View    @   backbone.js:1190
   child    @   backbone.js:1852
   (anonymous function) @   app.js:9
   n.Callbacks.j    @   jquery.js:2
   n.Callbacks.k.fireWith   @   jquery.js:2
   n.extend.ready   @   jquery.js:2
   K    @   jquery.js:2

0 个答案:

没有答案