Backbone js - 未捕获的类型错误:无法读取未定义的属性'on'

时间:2014-05-23 07:42:28

标签: javascript backbone.js underscore.js

我有一个使用Backbone框架的非常简单的ToDo List应用程序。

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>To do List</title>
    <style>
        .completed{
            text-decoration: line-through;
            color: #666;
        }
    </style>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.js"></script>
    <script type="text/javascript" src="js/underscore.js"></script>
    <script type="text/javascript" src="js/backbone.js"></script>
</head>
<body>

    <h1>My Todos</h1>
    <div id="tasks">

        <button class="add">Add Task</button>
        <button class="clear hide">Clear All</button>
        <ul></ul>           

    </div>

    <script id="taskTemplate" type="text/template">
        <span class="<%= completed ? 'completed' : 'incomplete' %>"><%= text %></span>
        <button class="complete"></button>
        <button class="delete"></button>
    </script>


    <script type="text/javascript">

        var Task = Backbone.Model.extend({
            defaults: {text: 'New task', completed: false}

        });

        var Tasks = Backbone.Collection.extend({
            model: Task,
            el: '#tasks',
            initialize: function(){
                this.collection = new Tasks;
                this.collection.on('add', this.appendNewTask, this);

                this.items = this.$el.children('ul');
            },

            add: function(){
                var text = prompt('What do you need to do?');
                var task = new Task({text: text});
                this.collection.add(task);
            },

            appendNewTask: function(task){
                var TasksView = new TasksView({model:task});
                this.items.append(TasksView.el);
            },

            completed: function(){
                return _.filter(this.models, function(model){
                    return model.get('completed');
                });
            }
        });

        var TasksView = Backbone.View.extend({
            tagName: 'li',
            el: '#tasks',
            template: _.template($('#taskTemplate').html()),

            initialize: function(){

                this.model.on('change', this.render, this);
                this.model.on('remove', this.unrender, this);
                this.render();
            },

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

            unrender: function(){
                this.$el.remove();
            },

            events: { 
                'click .add': 'add',
                'click .clear': 'clearCompleted',
                'click .delete': 'delete',
                'click .complete': 'updateStatus',
                'dblclick span': 'edit'
            },

            add: function(){
                    var text = prompt('What do you need to do?');
                    var task = new Task({text: text});
            },

            delete: function(){
                this.model.destroy();
                this.$el.remove();
            },

            updateStatus: function(){
                this.model.set('completed', !this.model.get('completed'));
            },

            edit: function(){
                var text = prompt('What should we change your task to?', this.model.get('text'))
                this.model.set('text',text);
            },

            clearCompleted: function(){
                var completedTasks = this.collection.completed();
                this.collection.remove(completedTasks);
            }

        });     

        new TasksView;

    </script>


    <!-- Template JS -->


</body>
</html>

当我访问并加载页面时,我可以在控制台日志中看到未捕获的javascript错误。

未捕获的TypeError:无法读取属性&#39; on&#39;第78行的未定义

查看指示行号的代码,它指向了这个

var TasksView = Backbone.View.extend({
    //.....
    initialize: function(){

        this.model.on('change', this.render, this); // this is the line the console is complaining
        this.model.on('remove', this.unrender, this);
        this.render();
    },
    //.....
});

在接下来的几个小时内查看并分析了代码之后,我还无法弄清楚为什么在尚未向TaskView Objects添加任务时需要实例化此模型。只要我在模型中添加或删除新的Task项,就应该初始化它。我不太明白这会如何引发异常。

顺便说一句,我是Backbone.js和Underscore.js的新手。我只是按照在线教程了解这些框架是如何工作的......

感谢。

1 个答案:

答案 0 :(得分:0)

您没有将任何模型绑定到您的视图。您可以在实例化新视图时传递模型和/或集合。这些属性将自动绑定到您视图的this.model / this.collection

您没有传递模型,因此在您的视图中未定义this.model。您应该传递空的任务列表,以便在以后填充时,onchange将被触发,您的视图将会重新呈现。

new TasksView({model: new Tasks()});