简体   繁体   中英

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

I am working on the Meteortips' Your Second Meteor Application tutorial, and I am at the end of Chapter 5: Routing, Part 2 .

When I go to http://localhost:3000/ I get the following screen:

在此处输入图片说明

And when I check the Chrome console, I get the following error:

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

Here is the content of my todos.js file:

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'
});

And here is the content of my todos.html file:

<!-- 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>

I must certainly be doing something wrong, but I cannot figure out what: any clue?

You're trying to setup events on an undeclared template.

You lack an addList template in your HTML.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM