Meteor: Uncaught TypeError: Cannot read property 'events' of undefined

Meteor: Uncaught TypeError: Cannot read property 'events' of undefined

我正在研究 Meteortips 的 Your Second Meteor Application 教程,第 5 章:路由,第 2 部分即将结束.

当我转到 http://localhost:3000/ 时,我看到以下屏幕:

并且当我检查 Chrome 控制台时,出现以下错误:

Uncaught TypeError: Cannot read property 'events' of undefined todos.js:85

这是我的 todos.js 文件的内容:

Todos = new Meteor.Collection('todos');
Lists = new Meteor.Collection('lists');

if(Meteor.isClient){
    // client code goes here
    Template.todos.helpers({
      'todo': function(){
          var currentList = this._id;
          return Todos.find({ listId: currentList }, {sort: {createdAt: -1}})
      }
    });

    Template.addTodo.events({
      'submit form': function(event){
        event.preventDefault();
        var todoName = $('[name="todoName"]').val();
        var currentList = this._id;
        Todos.insert({
            name: todoName,
            completed: false,
            createdAt: new Date(),
            listId: currentList
        });
        $('[name="todoName"]').val('');
      }
    });

    Template.todoItem.events({
    // events go here
      'click .delete-todo': function(event){
        event.preventDefault();
        var documentId = this._id;
        var confirm = window.confirm("Delete this task?");
        if(confirm){
            Todos.remove({ _id: documentId });
        }
      },

      'keyup [name=todoItem]': function(event){
        if(event.which == 13 || event.which == 27){
            $(event.target).blur();
        } else {
            var documentId = this._id;
            var todoItem = $(event.target).val();
            Todos.update({ _id: documentId }, {$set: { name: todoItem }});
        }
      },

      'change [type=checkbox]': function(){
        var documentId = this._id;
        var isCompleted = this.completed;
        if(isCompleted){
            Todos.update({ _id: documentId }, {$set: { completed: false }});
            console.log("Task marked as incomplete.");
        } else {
            Todos.update({ _id: documentId }, {$set: { completed: true }});
            console.log("Task marked as complete.");
        }
      }

    });

    Template.todoItem.helpers({
      'checked': function(){
          var isCompleted = this.completed;
          if(isCompleted){
              return "checked";
          } else {
              return "";
          }
      }
    });

    Template.todosCount.helpers({
      'totalTodos': function(){
          var currentList = this._id;
          return Todos.find({ listId: currentList }).count();
      },
      'completedTodos': function(){
          var currentList = this._id;
          return Todos.find({ listId: currentList, completed: true }).count();
      }
    });

    Template.addList.events({
      'submit form': function(event){
          event.preventDefault();
          var listName = $('[name=listName]').val();
          Lists.insert({
            name: listName
          }, function(error, results){
              Router.go('listPage', { _id: results });
          });
          $('[name=listName]').val('');
      }
    });

    Template.lists.helpers({
      'list': function(){
          return Lists.find({}, {sort: {name: 1}});
      }
    });

}

if(Meteor.isServer){
    // server code goes here
}

Router.route('/register');
Router.route('/login');
Router.route('/', {
    name: 'home',
    template: 'home'
});
Router.route('/list/:_id', {
    name: 'listPage',
    template: 'listPage',
    data: function(){
        var currentList = this.params._id;
        return Lists.findOne({ _id: currentList });
    }
});
Router.configure({
    layoutTemplate: 'main'
});

这是我的 todos.html 文件的内容:

<!-- Templates -->

<template name="todoItem">
    <li class="{{checked}}">
        <input type="checkbox" {{checked}}>
        <input type="text" value="{{name}}" name="todoItem">
        [<a href="#" class="delete-todo">Delete</a>]
    </li>
</template>

<template name="todos">
    <p>{{_id}}</p>
    {{> addTodo}}
    <ul>
    {{#each todo}}
        {{> todoItem}}
    {{/each}}
    </ul>
    {{> todosCount}}
</template>

<template name="addTodo">
    <form>
        Create a task:
        <input type="text" placeholder="Type a task here..." name="todoName">
    </form>
</template>

<template name="todosCount">
{{#if totalTodos}}
    <p>You have completed {{completedTodos}} out of {{totalTodos}} tasks.</p>
{{/if}}
</template>

<template name="register">
    <h2>Register</h2>
</template>

<template name="login">
    <h2>Login</h2>
</template>

<template name="home">
    <p>Welcome to the Todos application.</p>
</template>

<template name="main">
    <h1>Todos</h1>
    {{> navigation}}
    {{> lists}}
    {{> yield}}
    <hr />
    <p>Copyright &copy; Todos, 2014-2015.</p>
</template>

<template name="navigation">
    <ul>
        <li><a href="{{pathFor route='home'}}">Home</a></li>
        <li><a href="{{pathFor route='register'}}">Register</a></li>
        <li><a href="{{pathFor route='login'}}">Login</a></li>
    </ul>
</template>

<template name="lists">
    <h2>Lists</h2>
    {{> addList}}
    <ul>
        {{#each list}}
            <li><a href="{{pathFor route='listPage'}}">{{name}}</a></li>
        {{/each}}
    </ul>
</template>

<template name="listPage">
    <h2>Tasks: {{name}}</h2>
    {{> todos}}
</template>

我肯定做错了什么,但我不知道是什么:有线索吗?

您正在尝试在未声明的模板上设置事件。

您的 HTML 中缺少 addList 模板。