As I develop a Backbone application that includes a section for viewing reports, there are three key components: a menu of report links, the title of the displayed report, and the content of the displayed report. Users are expected to click on a report link, triggering the retrieval of relevant model data. Subsequently, both the report title and content should be updated accordingly. However, determining how view bindings should operate presents a challenge, especially since each report may yield slightly different data requiring distinct view templates. You can access my code on JSFiddle (please note that the fetch method has been overridden for demonstration purposes).
My current setup involves a Backbone model for each report and a Backbone collection containing all reports:
App.Models.Report = Backbone.Model.extend();
App.Collections.Reports = Backbone.Collection.extend({
model: App.Models.Report,
url: "/reports"
});
The menu view is linked to the collection and upon clicking, it sets App.State.title
and App.State.cid
, which are then observed by the other two views:
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); // storing 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 challenge lies in handling the report content; currently, it listens for changes to App.State.cid
and triggers a fetch operation on the corresponding model using that cid. Upon fetching, the model is populated with a sub-collection of report rows. The report content view then updates its HTML based on the sub-collection data and aims 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()); // intention to dynamically set this
html += template(model.toJSON());
});
self.$el.html(html);
}
});
}
});
1) Could you provide feedback on whether this implementation is appropriate for managing multiple views within a collection-oriented scenario?
2) How can I ensure the correct template is applied to each individual report? My current approach involves explicitly passing the view template for report A. I have considered storing it on the model, but I believe the template should be associated with the view itself.