Reputation: 1695
Here is how my Backbone Router looks like
define([
"jquery",
"underscore",
"backbone"
], function ($, _, Backbone) {
return Backbone.Router.extend({
routes: {
"overview": "overview"
},
overview: function () {
require([
"views/overview",
"models/user-collection",
"grid",
"spreadsheet"
], function (OverviewView, TestCollection, GridView, SpreadSheetView) {
// Data
var collection = new TestCollection();
// Main view
var view = new OverviewView({
el: "#page",
collection: collection
});
// Sub view #1
var gridView = new GridView({
el: "#backgridWrapper"
});
// Sub View #2
var spreadsheetView = new SpreadSheetView({
el: "#handsontableWrapper"
});
// Flow
collection.fetch({
success: function () {
view.render();
gridView.render();
spreadsheetView.render();
}
});
});
}
});
});
As you can see there are several views:
I've did a lot of searching on how to organize the views and sub-views in Backbone, however all of them supposed to create a new sub-view instance directly within a view definition, so that router only knows about Main view...
So the question is - is it a good idea to handle sub-views at a router, instead of directly at view constructor?
Upvotes: 0
Views: 102
Reputation: 43156
The router should be just handling routes and initializing stuff.
Things like fetching data should go in the view that uses it - The view displays the data or error messages (in case of a failure), so I think it's wise to let the view fetch the data rather than some router who's only interested in the routes and have no interest in the data.
and I prefer initializing the sub views, inside their parent view, rather than somewhere else. The parent - child relationship itself justifies that, you better keep the children with their parents than a stranger so they will be under better control and you can easily find them later as well :)
Mostly it's a matter of opinion, but the thing is if you don't, all your code will soon get cluttered in the router rather than being well organized.
Below is how I'll structure the same thing.
Note that I'm initializing child views as part of parent views render method. It could be done when the parent view is initialized, but I see no point in doing so unless the parent view successfully fetches data and is proceeding to render itself.
define([
"jquery",
"underscore",
"backbone"
], function($, _, Backbone) {
return Backbone.Router.extend({
routes: {
"overview": "overview"
},
overview: function() {
require(["views/overview"], function(OverviewView) {
// initialize Main view
var view = new OverviewView({
el: "#page"
});
});
}
});
});
define([
"jquery",
"underscore",
"backbone",
"models/user-collection",
"grid",
"spreadsheet"
], function($, _, Backbone, TestCollection, GridView, SpreadSheetView) {
return Backbone.View.extend({
initialize: function(options) {
this.collection = new TestCollection();
this.fetchData();
},
events: {},
render: function() {
// rendering subviews is part of rendering their parent view.
//I prefer to do that here
// Sub view #1
this.gridView = new GridView({
el: "#backgridWrapper"
});
// Sub View #2
this.spreadsheetView = new SpreadSheetView({
el: "#handsontableWrapper"
});
//Below lines can be handled while initializing the respective view
// (In their initialize() method, or after fetching some data etc
// or can be chained with the above initialization if their render() method returns a reference to itself (`return this`)
this.gridView.render();
this.spreadsheetView.render();
},
fetchData: function() {
var view = this;
this.collection.fetch({
success: function() {
view.render();
}
});
}
});
});
side note : I strongly suggest not to put a collection under models
folder.
Upvotes: 1