在Backbone中,this.model是未定义的,为什么?

时间:2013-02-14 01:33:05

标签: javascript backbone.js backbone-views

我到处寻找答案,但对我发现的内容并不满意。

问题是,我正在从Addy Osmani做一个教程,在Backbone中制作一个'Todo'应用程序,但是当我看到控制台时,我收到错误说this.model is undefined

我甚至试过这个SO答案Backbone model error displayed in console,但我仍然得到同样的错误。请告诉我有什么问题。

顺便说一下,this.modelthis.collection是什么?我知道他们引用了Backbone.ModelBackbone.Collection,但它们是如何运作的?我问这个是因为在我明确定义this.collectionthis.model.models时,另一个教程ModelCollection也未定义。

非常感谢

JS:

//Model
var Todo = Backbone.Model.extend({

  defaults: {
    title: 'Enter title here',
    completed: true
  },

  validate: function(attrs) {
    if (attrs.title === undefined) {
        return 'Remember to enter a title';
    }
  },

  initialize: function() {
    console.log('This model has been initialized');

    this.on('change:title', function() {
        console.log('-Title values for this model have changed');
    });

    this.on('invalid', function(model, error) {
        console.log(error);
    });
  } 
});

//View
var TodoView = Backbone.View.extend({

  el: '#todo',
  tagName: 'li',
  template: _.template($('#todoTemplate').html()),

  events: {
    'dbclick label': 'edit',
    'click .edit': 'updateOnEnter',
    'blur .edit': 'close'
  },

  initialize: function() {
    _.bindAll(this, 'render');
            this.render();

  },

  render: function() {
    this.$el.html(this.template(this.model.toJSON()));
    this.input = this.$('.edit');
    console.log(this.model.toJSON());
    return this;
  },

  edit: function() {
    //do something...
  },

  close: function() {
    //do something...
  },

  updateOnEnter: function() {
    //do something...
  }
});

var todoview = new TodoView();
console.log(todoview.el);

//Collection
var TodoList = Backbone.Collection.extend({
  model: Todo
});

3 个答案:

答案 0 :(得分:11)

您需要实例化ModelCollection并将其传递给您的视图。否则,在TodoView上调用render方法时,this.model将为null。

例如,尝试重新排列代码的最后几行,如下所示:

//Collection
var TodoList = Backbone.Collection.extend({
  model: Todo
});

var todos = new TodoList();

var todoview = new TodoView({model: todos});

从那时起,您可以修改待办事项(Collection)并且您的视图可以收听待办事件的事件并相应地重新渲染。

答案 1 :(得分:3)

你没有说,但我认为你得到的错误发生在render()方法中。

您的问题是您定义了一种新类型的模型(var Todo = Backbone.Model.extend({...)但是您从未实例化它,也没有将模型传递给todoview构造函数。

所以至少你需要这样做:

var todomodel = new Todo();

var todoview = new TodoView({
    model: todomodel
});

答案 2 :(得分:2)

另一个问题的答案是您的问题的答案:在实例化视图时,您没有将模型传递给视图。

var model = new Todo();
var todoview = new TodoView({model: model});

将对象传递给视图的构造函数时,它会查找某些键并将它们直接附加到视图中。

您可以通过查看Backbone's source并搜索viewOptions来查看哪些内容。

这就是this.modelthis.collection自动附加到视图this的方式。