骨干应用程序视图中的“未捕获的TypeError:undefined不是函数”

时间:2014-05-09 00:25:04

标签: javascript backbone.js

我正在尝试在浏览器中运行我的js应用程序,但是当我这样做时,我在控制台中收到此错误:

“Uncaught TypeError:undefined不是函数”app.js:18

我已阅读并尝试过类似问题的其他答案,但没有成功。

错误行18的代码:

var 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.input = this.$("#new-todo");
  this.allCheckbox = this.$("#toggle-all")[0];

  this.listenTo(Todos, 'add', this.addOne); //the line with the error
  this.listenTo(Todos, 'reset', this.addAll);
  this.listenTo(Todos, 'all', this.render);

  this.footer = this.$('footer');
  this.main = $('#main');

      Todos.fetch();
},

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

      if (Todos.length) {
        this.main.show();
        this.footer.show();
        this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
      } else {
        this.main.hide();
        this.footer.hide();
      }

      this.allCheckbox.checked = !remaining;
    },

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

addAll: function() {
      Todos.each(this.addOne, this);
    },

createOnEnter: function(e) {
      if (e.keyCode != 13) return;
      if (!this.input.val()) return;

      Todos.create({title: this.input.val()});
      this.input.val('');
    },

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

toggleAllComplete: function () {
      var done = this.allCheckbox.checked;
      Todos.each(function (todo) { todo.save({'done': done}); });
    }

});

这是我的collection.js代码:

var TodoList = Backbone.Collection.extend({
model: Todo,
localStorage: new Backbone.LocalStorage("todos-backbone"),

done: function(){
return this.where({done: true});
},

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

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

comparator: 'order'

});

var Todos = new TodoList();

4 个答案:

答案 0 :(得分:0)

如果要使用listenTo,则需要升级Backbone版本。来自fine ChangeLog

  

0.9.9 - Dec。 13,2012

     
      
  • listenTo stopListening 添加到活动中。它们可以用作onoff的控制反转风格,以便方便地解除对象当前正在侦听的所有事件的绑定。 view.remove()会自动调用view.stopListening()
  •   

listenTo方法出现在Backbone 0.9.9中,但您使用的是0.9.1。

阅读ChangeLog并升级Backbone版本。

答案 1 :(得分:0)

this.listenTo(Todos,' add',this.addOne);

您正在使用Todos作为引用集合的对象,但该集合的对象既未在视图中传递也未在视图中创建。

如果你想传递

var mycollection = new Todos();
new AppView({ myCollection: mycollection});

由于我们传递了一个键值,我们可以在视图中将其取回,如

this.myCollection.add(model) or
this.myCollection.reset(); //to reset the collection

如果要创建一个集合对象,可以直接使用相同的方式

var mycollection = new Todos();

集合回调函数可以在集合本身内部定义。这将有助于在多个视图上重用该函数。

答案 2 :(得分:0)

遇到同样的问题,看了几眼之后,我意识到我在初始化时错误拼写了元素的名称:

  this.allCheckbox = this.$("#toggle-all")[0];

因此,请检查html

中元素的名称

答案 3 :(得分:-1)

确定你的问题不在那条线上,而是:

this.input = this.$("#new-todo");
this.allCheckbox = this.$("#toggle-all")[0];