I've looked everywhere for an answer but wasn't satisfied with what I've found.
The issue is, I'm doing a tutorial from Addy Osmani to make a 'Todo' app in Backbone, but when I look at the console, I get an error saying that this.model is undefined
.
I even tried this SO answer Backbone model error displayed in console, but I still get the same error. Please tell me what is wrong.
By the way, what are this.model
or this.collection
? I've got an idea that they refer to Backbone.Model
and Backbone.Collection
but how do they work? I'm asking this because in another tutorial this.collection
and this.model.models
were also undefined, when I've clearly defined the Model
and Collection
.
Many Thanks
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
});
I've looked everywhere for an answer but wasn't satisfied with what I've found.
The issue is, I'm doing a tutorial from Addy Osmani to make a 'Todo' app in Backbone, but when I look at the console, I get an error saying that this.model is undefined
.
I even tried this SO answer Backbone model error displayed in console, but I still get the same error. Please tell me what is wrong.
By the way, what are this.model
or this.collection
? I've got an idea that they refer to Backbone.Model
and Backbone.Collection
but how do they work? I'm asking this because in another tutorial this.collection
and this.model.models
were also undefined, when I've clearly defined the Model
and Collection
.
Many Thanks
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
});
Share
Improve this question
edited May 23, 2017 at 12:08
CommunityBot
11 silver badge
asked Feb 14, 2013 at 1:33
ShaozShaoz
10.7k26 gold badges75 silver badges100 bronze badges
3 Answers
Reset to default 13You need to instantiate a Model
or Collection
and pass it to your View. Otherwise, when the render method is called on your TodoView, this.model
will be null.
For example, try rearranging the last few lines of your code like this:
//Collection
var TodoList = Backbone.Collection.extend({
model: Todo
});
var todos = new TodoList();
var todoview = new TodoView({model: todos});
From that point onward, you can modify todos (which is a Collection
) and your view can listen to todos' events and re-render accordingly.
The answer in the other question is the answer to your question: you're not passing the model to the view when you instantiate the view.
var model = new Todo();
var todoview = new TodoView({model: model});
When you pass an object to a view's constructor, it looks for certain keys and attaches them directly to the view.
You can see which by looking at Backbone's source and searching for viewOptions
.
That's how you get the this.model
and this.collection
automatically attached to the view's this
.
You didn't say, but I assume the error you are getting is occurring in the render() method.
Your problem is that you define a new type of model (var Todo = Backbone.Model.extend({...
) however you never instantiate it, nor do you pass the model to the todoview constructor.
So at the very least you need to do:
var todomodel = new Todo();
var todoview = new TodoView({
model: todomodel
});