I reorganized my fully-working Backbone.js project and moved all my models, collections and views into separate files, and did a little rewriting, and now it won't render. I've tried everything I can think of. Any tips?
var SessionView = Backbone.View.extend({
model: Session,
el: '#list',
template: _.template($('#session-template').html()),
initialize: function () {
this.model.bind('change', _.bind(this.render, this));
this.render();
},
render: function () {
this.$el.html(this.template({sessions: sessionList}));
return this;
}
});
var sessionView = new SessionView();
var SessionListView = Backbone.View.extend({
el: '#list',
model: sessionList,
initialize: function () {
sessionList.bind('add', this.add, this);
sessionList.bind('reset', this.add, this);
sessionList.fetch();
},
render: function () {
var view = new sessionListView();
this.$el.append(view.render().el);
new SessionView({model: Session});
return this;
}
});
var sessionListView = new SessionListView();
Few things that I noticed:
Backbone.View
does not have a model property. Only Backbone.Collection
has a model property, which backbone will use to create an instance of model using the specified model constructor (blueprint) and data passed to it.
But views doesn't have a functionality like this (as far as I know). People usually pass an instance of a specific type of model with the options while creating a view, that's not the same as specifying a model property which points to a model constructor in the View's constructor.
sessionList
doesn't seems to be an instance of a model (since it is specified in the view's constructor. If it's an instance it'll be shared by all the SessionListView
instances which is not the desired behavior in most cases) and seems to be undefined
in the following:new SessionView({model: Session});
Session
doesn't look like an instance of a model (Doesn't start with a capital letter, hoping you're following naming conventions) and also seems to be undefined
Well nothing is stopping you from specifying a model constructor in view's constructor or passing a model constructor into the view, but then you should make an instance of it (mostly while initializing) inside the view to work with. In other words you can not do blueprintOfAModel.bind('change'..);
and you should build an actual model for the view to work with.
You seems to be creating new SessionListView
in the render
method of SessionListView
itself with var view = new sessionListView();
won't that create infinite number of SessionListView
instances when you simply try to create one..?
Well by looking at it again, you are not calling the actual constructor SessionListView
with the new
operator, but with an instance of it (sessionListView
) which is likely to throw an error.
Both SessionView
and SessionListView
points to the same element, which seems weird. I haven't seen people doing that before since modifying the el
of one view will have an impact on the other view, which is not desired in most practical cases.
Also judging by the names, since you have a list view of session, SessionView
should not be pointing to a particular element with an id
selector. You should create a new element for each SessionView instance. Backbone will do that for you if you don't specify el
property.
(I'd say you created an unintentional mess that wasn't there with a little rewrite :)
To make sense, your code should look somewhat like the following. Note that things starting with capital letter are constructor functions and things starting with small letters are object instances
var Session = Backbone.Model.extend({
defaults: {},
initialize: function() {}
});
var SessionList = Backbone.Collection.extend({
model: Session,
initialize: function() {}
});
var SessionView = Backbone.View.extend({
initialize: function() {
this.model.bind('change', _.bind(this.render, this));
this.render();
},
template: _.template($('#session-template').html()),
render: function() {
this.$el.html(this.template({
session: this.model
}));
return this;
}
});
var SessionListView = Backbone.View.extend({
el: '#list',
initialize: function() {
this.collection.bind('add', this.add, this); // method doesn't exist, should throw error
this.collection.bind('reset', this.add, this); // same here
this.collection.fetch(); // <--- watch out, this happens asynchronously
},
render: function() {
// iterate through collection, create instances of SessionView and append to el
return this;
}
});
var sessionList = new SessionList(); // will create n number of Session instances in future
var sessionListView = new SessionListView({ // will create n number of SessionView instances in future
collection: sessionList
});