I'm creating a Backbone app with a section to view reports; the section has three parts: a menu of report links, the title of the displayed report, and the content of the displayed report. The user is to click on a report link, which will fetch the associated model's data. Then the report title and content should update accordingly. However, I'm not sure how the view bindings should work, and each report may return slightly different data that requires a different view template. Here's my JSFiddle (fetch method overridden just for this example)
Right now, I have a Backbone model for each report and a Backbone collection of all the reports:
App.Models.Report = Backbone.Model.extend();
App.Collections.Reports = Backbone.Collection.extend({
model: App.Models.Report,
url: "/reports"
});
The menu view is tied to the collection and on click, sets App.State.title
and App.State.cid
, which the other two views are listening to:
App.Views.ReportLink = Backbone.View.extend({
tagName: 'li',
className: 'is-clickable',
initialize: function() {
this.render();
},
render: function() {
this.el.innerHTML = this.model.get('title');
this.$el.attr('data-CID', this.model.cid); // store the model's cid
}
});
App.Views.ReportMenu = Backbone.View.extend({
tagName: 'ul',
initialize: function() {
this.listenTo(this.collection, 'reset', this.render)
this.render();
this.$el.on('click', 'li', function() {
App.State.set({
'title': this.innerHTML,
'cid': $(this).attr('data-CID') // cid of the clicked view's model
});
});
},
The difficulty is with the report content; what it currently does is listen for changes to App.State.cid
and then calls fetch on the given model with that cid. This fetch populates the model with a sub-collection of report rows. The report content view then set its html based on the sub-collection data, and it is also supposed to apply the correct template to the data:
App.Views.ReportContent = Backbone.View.extend({
initialize: function(attrs) {
this.listenTo(this.model, 'change:cid', this.render);
this.reportsCollection = attrs.reportsCollection;
},
render: function() {
var self = this,
cid = this.model.get('cid'),
model = this.reportsCollection.get(cid);
model.fetch({
success: function() {
var html = '';
model.subCollection.each(function(model) {
var template = _.template($('#templateReportA').html()); // want to dynamically set this
html += template(model.toJSON());
});
self.$el.html(html);
}
});
}
});
1) Is this the correct sort of implementation for this type of multiple view situation with a collection?
2) How can I pass the correct template that needs to apply for each individual report? Right now I'm explicitly passing the view template for report A. I can think of storing it on the model but the template should be associated with the view.