Reputation: 5568
I need to be able to pass different template IDs to different routes.
(function() {
window.App = {
Models: {},
Collections: {},
Views: {},
Router: {}
};
var vent = _.extend({}, Backbone.Events);
_.templateSettings.interpolate = /\[\[(.+?)\]\]/g;
App.Router = Backbone.Router.extend({
routes: {
'' : 'index',
'send-message' : 'sendMessage',
'*other' : 'other'
},
index: function() {
t = new (App.Collections.Tables.extend({ url: 'main-contact'}))();
tables = App.Views.Tables({ collection: t, template: 'mainContactTemplate' });
$('#web-leads').html(tables.el);
},
sendMessage: function() {
// t = new (App.Collections.Tables.extend({ url: 'send-message'}))();
// tables = new App.Views.Tables.extend({ collection: t, template: template('sendMessageTemplate')});
// $('#web-leads').html(tables.el);
},
other: function() {
}
});
// Main Contact
App.Models.Table = Backbone.Model.extend({});
App.Collections.Tables = Backbone.Collection.extend({
model: App.Models.Table,
initialize: function(models, options) {
this.fetch({
success: function(data) {
//console.log(data.models);
}
});
if (options) {
this.url = this.url || options.url;
}
}
});
App.Views.Tables = Backbone.View.extend({
tagName: 'ul',
initialize: function() {
this.collection.on('reset', this.render, this);
},
render: function() {
return this.collection.each(this.addOne, this);
},
addOne: function(model) {
var t = new App.Views.Table({ model: model});
this.$el.append(t.render().el);
return this;
}
});
App.Views.Table = Backbone.View.extend({
tagName: 'li',
initialize: function(options) {
this.template = options.template;
console.log(this.options);
},
retrieveTemplate: function(model) {
return _.template($('#' + this.template).html(), model);
},
render: function() {
this.$el.html(this.retrieveTemplate(this.model.toJSON()));
return this;
}
});
new App.Router();
Backbone.history.start();
})();
But I get an error than n is undefined
. I think I need to pass this.template
into my retrieveTemplate
function. But shouldn't it already be set? This code works, by the way, if I hard code in the name of the template ID in the retrieveTemplate
function.
EDIT: the template isn't being passed from the call in the router. That's where this is breaking down.
EDIT: I took out the call to extend in the second line of the index route and now I get this._configure is not a function
WORKING VERSION:
(function() {
window.App = {
Models: {},
Collections: {},
Views: {},
Router: {}
};
var vent = _.extend({}, Backbone.Events);
_.templateSettings.interpolate = /\[\[(.+?)\]\]/g;
App.Router = Backbone.Router.extend({
routes: {
'' : 'index',
'send-message' : 'sendMessage',
'*other' : 'other'
},
index: function() {
var t = new (App.Collections.Tables.extend({ url: 'main-contact'}))();
var tables = new (App.Views.Tables.extend({ collection: t, options: {template: 'mainContactTemplate' }}))();
$('#web-leads').html(tables.render().el);
},
sendMessage: function() {
// t = new (App.Collections.Tables.extend({ url: 'send-message'}))();
// tables = new App.Views.Tables.extend({ collection: t, template: template('sendMessageTemplate')});
// $('#web-leads').html(tables.el);
},
other: function() {
}
});
// Main Contact
App.Models.Table = Backbone.Model.extend({});
App.Collections.Tables = Backbone.Collection.extend({
model: App.Models.Table,
initialize: function(models, options) {
this.fetch({
success: function(data) {
//console.log(data.models);
}
});
if (options) {
this.url = this.url || options.url;
}
}
});
App.Views.Tables = Backbone.View.extend({
tagName: 'ul',
initialize: function(options) {
this.collection.on('reset', this.render, this);
this.template = this.options.template;
},
render: function() {
this.collection.each(this.addOne, this);
return this;
},
addOne: function(model, options) {
//console.log(model);
var t = new App.Views.Table({ model: model, template: this.options.template});
this.$el.append(t.render().el);
return this;
}
});
App.Views.Table = Backbone.View.extend({
tagName: 'li',
initialize: function(options) {
//console.log(this.options);
this.template = this.options.template;
},
retrieveTemplate: function(model) {
return _.template($('#' + this.template).html(), model);
},
render: function() {
//console.log(this);
this.$el.html(this.retrieveTemplate(this.model.toJSON()));
return this;
}
});
new App.Router();
Backbone.history.start();
})();
Upvotes: 2
Views: 765
Reputation: 434685
Your router says this:
tables = App.Views.Tables({ collection: t, template: 'mainContactTemplate' });
So you're giving a template: '...'
to App.Views.Tables
. The initialize
in App.Views.Tables
looks like this:
initialize: function() {
this.collection.on('reset', this.render, this);
}
so it ignores the template
option. If we look at App.Views.Table
(singular!), we see this:
initialize: function(options) {
this.template = options.template;
console.log(this.options);
}
but App.Views.Table
is instantiated without a template
option:
var t = new App.Views.Table({ model: model});
You need to fix how you use App.Views.Table
. Backbone will put a view's constructor options in this.options
for you so you just need to say:
var t = new App.Views.Table({ model: model, template: this.options.template });
A couple other things to consider:
index
method, you should have var t
and var tables
rather than just t
and tables
.render
method conventionally returns this
so that you can say $x.append(v.render().el)
so you might want to adjust your render
methods to match the convention.Upvotes: 1
Reputation: 11
You probably need to bind the context. Underscore can help you with that.
.bindAll or .bind should do it.
I typically just use _.bindAll during initialization as shown below.
...
initialize: function(options) {
_.bindAll(this); // apply appropriate context
this.template = options.template;
},
...
Hope this helped, best of luck.
Upvotes: 1