骨干JS - 未捕获类型的错误:无法读取“开”的未定义属性 [英] Backbone js - Uncaught type error: Cannot read property 'on' of undefined

查看:1157
本文介绍了骨干JS - 未捕获类型的错误:无法读取“开”的未定义属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用了框架骨干下面一个非常简单的待办事项列表应用程序。

I have the following a very simple ToDo List app using Backbone framework.

<!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错误控制台日志。

When I visit and load the page, and I could see an uncaught javascript error in the console log.

未捕获类型错误:无法未定义在线阅读78'上'属性。

Uncaught TypeError: Cannot read property 'on' of undefined on line 78.

通过在indictaed行号code来看,它指出了这个

Looking through the code at the indictaed line number, it pointed to this

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();
    },
    //.....
});

这盯着在接下来的几个小时,分析了code后,我无法弄清楚为什么这个模式需要在没有任务已添加到TaskView被实例化对象呢。应该尽快添加或删除新任务项进入模型对其进行初始化。我不太明白这将如何抛出异常。

After staring this for the next couple of hours and analysed the code, I couldn't figure out why this model needs to be instantiated when no tasks have been added to the TaskView Objects yet. It should be initialized as soon as I add or remove a new Task item into the model. I don't quite understand how this would throw an exception.

顺便说一句,我是一个很新的Backbone.js的和Underscore.js。我只是下面的一个在线教程弄清楚这些框架是如何工作的?

BTW, I'm a very new to Backbone.js and Underscore.js. I'm just following an online tutorial to figure out how these frameworks work...

感谢。

推荐答案

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

You are not binding any model to your view. You can pass a model and/or collection when instantiating your new view. These properties will automatically be bound to this.model / this.collection of your view.

您没有传递的模型,因此 this.model 在您的视图定义。你应该通过空taskslist这样,当它的后面填充,的onchange 将被触发,你的观点就会重新呈现。

You are not passing a model so this.model is undefined in your view. You should pass the empty taskslist so that when it's populated later, the onchange will be triggered and your view will rerender.

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

这篇关于骨干JS - 未捕获类型的错误:无法读取“开”的未定义属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆