I organised the file structure of my web app, which is using RequireJs and Backbone.Marionette,in this way:
|- main.js
|- app.js
|- /subapp1
|- subapp1.js
|- subapp1.router.js
|- /subapp2
|- subapp2.js
|- subapp2.router.js
|- /colections
|- /views
To loads the modules I use requireJs.
Here's my code, for each module I put some questions.
// main.js
define([
'app',
'subapp1/subapp1.router',
'subapp2/subapp2.router'
], function (app) {
"use strict";
app.start();
});
Questions:
1) Is right to load asynchronously the app and subapps even if subapps need app?
2) for the subApps is right to load the router which needs the app?
// app.js
/*global define*/
define([
'backbone',
'marionette',
'models/user'
], function (Backbone, Marionette, UserModel) {
"use strict";
var App = new Marionette.Application();
App.addRegions({
header: '#header',
sidebar: '#sidebar',
mainColumn: '#main-column',
rightColumn: '#right-column'
});
App.on("initialize:before", function () {
this.userModel = new UserModel();
this.userModel.fetch();
});
App.on("initialize:after", function () {
Backbone.history.start();
});
return App;
});
Questions:
3) Since the subApps
could need some models
I decided to load it in app.js
. Is it right this way?
// subapp1/subapp1.js
/*global define*/
define([
'app',
'subapp1/views/sidebarView',
'subapp1/views/headerView'
], function (app, SidebarView, HeaderView) {
"use strict";
app.addInitializer(function(){
app.header.show(new HeaderView({userModel: app.userModel}));
app.sidebar.show(new SidebarView({userModel: app.userModel}));
});
});
Questions:
4) about this module I am not sure about the app.addInitializer
.
I am not sure for example if the app.userModel
will be fetched when I perform app.header.show
.
Should it be ok?
// subapp1/subapp1.router.js
/*global define*/
define([
'marionette',
'tasks/app'
], function (Marionette, app) {
"use strict";
var Router = Marionette.AppRouter.extend({
appRoutes: {
'tasks': 'tasks',
'tasks/:id': 'taskDetail',
'*defaults': 'tasks'
}
});
return new Router({
controller: app
});
});
Question:
5) is it ok to load from the main.js
the subapp1/subapp1.router
instead of subapp1/subapp1
?
1) Is right to load asynchronously the app and subapps even if subapps need app?
You should be able to asynchronously load your
app
and any of thesub-apps
. If thesub-apps
require the mainapp
, they should list it as a dependency. RequireJS will resolve the dependencies for you.Only thing you should watch out for are circular dependencies, but that shouldn't be anything you can't fix.
2) for the subApps is right to load the router which needs the app?
Listing the
routers
of yoursub-apps
in yourmain.js
sounds right to me.3) Since the
subApps
could need somemodels
I decided to load it inapp.js
. Is it right this way?A module should list any and all other modules it uses as its dependencies. Therefore, if
app.js
andsubapp1/subapp1.js
both requiremodels/user.js
, they should both listmodels/user.js
as one of their dependencies.This way, if you change any of the modules in such a way that it no longer requires
models/user.js
you can remove the dependency from that particular module without risk of missing dependencies in another module.Besides being the savest way of managing your dependencies, it's also nice and clear for other developers or even yourself when looking at your code in the future.
4) about this module I am not sure about the
app.addInitializer
.I am not sure for example if the
app.userModel
will be fetched when I performapp.header.show
. Should it be ok?Fetching data should be initiated manually. While showing a view in a
Region
does trigger theView
to be rendered, it doesn't trigger the view'sModel
orCollection
to fetch data.What you can do, is to let your
view
listen to the events on yourModel
orCollection
and re-render the view once theModel
orCollection
has successfully fetched new data. Marionette'sCollectionView
automatically binds some events toadd
,change
andremove
events of it'sCollection
in orde to automatically manage it'sItemViews
if theCollection
changes in any way.5) is it ok to load from the
main.js
thesubapp1/subapp1.router
instead ofsubapp1/subapp1
?As I already stated in question 2, it's good to load your routers in
main.js
.One reason to do this, is that you could decide not to load all your
sub-apps
up front, but instead only load them once they're actually needed. The moment such asub-app
's routes get triggered is as good a time as any to load thatsub-app
's core module and possibly some of it's dependencies, but that would of-course require thesub-app
'sRouter
to be activated before thesub-app
is loaded.