We have modularised
our marionette application into modules
. However now we are at a complete loss on how to handle the different entry points from the router and restore the state in the correct regions.
The problem being the application is top down, the regions are nested inside another region etc etc... (see diagram). What makes this difficult is that the top down is also not a straight line, there are menus in each module that dictate which other module to load below it. We just can't figure out how to pass along a chain of commands or instructions to replicate the state.
Each module has its own layout/region and triggers another module passing as parameter again another region
and model
.
We essentially acknowledged 3 distinct ways a state can come into place.
some code
@MyApp = do (Backbone, Marionette) ->
App = new Marionette.Application
App.addRegions
mainRegion: "#main"
model = ...
App.execute "module:1:load", App.mainRegion, model
## -------------------------------------------------------
@MyApp.module "ModuleOne", (ModuleOne, App, Backbone, Marionette, $, _) ->
@startWithParent = false
## MODULE
class ModuleOne.Show.Controller extends Marionette.Controller
initialize: (options) ->
@layout = @getLayoutView()
@region = options.region
@model = options.model
@listenTo @layout, "show", =>
@showRegionOne()
@showRegionTwo()
@region.show(@layout)
showRegionTwo: ->
App.execute "module:2:load", @layout.regionTwo, @model
...
## API
API =
show: (region, model) ->
new ModuleOne.Show.Controller
region: region
model: model
App.vent.on "module:1:load", (region, model) ->
API.show region, model
## ROUTER
class ModuleOne.Router extends Marionette.AppRouter
routes:
"path1/*subroute" : "pathOne"
pathOne: (hash) ->
## this gets triggered on URL enter if /path1 is in URL
new App.ModuleTwo.Router("path1")
App.addInitializer ->
new ModuleOne.Router
## -------------------------------------------------------
@MyApp.module "ModuleTwo", (ModuleTwo, App, Backbone, Marionette, $, _) ->
@startWithParent = false
## MODULE
...
## API
API =
show: (region, model) ->
new ModuleTwo.Show.Controller
region: region
model: model
App.vent.on "module:2:load", (region, model) ->
API.show region, model
## ROUTER
API_ROUTER =
pathTwo: ->
new App.ModuleThree.Router("path1/path2")
class ModuleTwo.Router extends Marionette.SubRouter
controller: API_ROUTER
appRoutes:
"path2/*subroute" : "pathTwo"
## -------------------------------------------------------
@MyApp.module "ModuleThree", (ModuleThree, App, Backbone, Marionette, $, _) ->
@startWithParent = false
## MODULE
## API
API =
show: (region, model) ->
new ModuleThree.Show.Controller
region: region
model: model
App.vent.on "module:3:load", (region, model) ->
API.show region, model
## ROUTER
API_ROUTER =
pathThree: ->
new App.ModuleFour.Router("path1/path2/path3")
class ModuleThree.Router extends Marionette.SubRouter
controller: API_ROUTER
appRoutes:
"path3/*subroute" : "pathThree"
extra notes
We have played with Marionette.SubRouter
which allows us to modularize the routes definition in that each module only knows about it's own relative URL and doesn't know what's before it.
Currently if the user goes to /path1/path2/path3/path4
we can pick it up and set a trigger hook along the way and in order at path1
path2
path3
path4
. The other problem here is then when the user presses forward / backward, we then after only get the end hooks triggered i.e. path3
so we got stuck here again and thought we are doing this wrong.
Should we try to recursively tell it to load from the end of the route backwards to the root module4(path4) > module3(path 3) > module(path 2) > module1(path 1)
OR should we figure out a mechanism to instruct each module the paths to take downwards path 1 > path 2 > path 3 > path 4
I would suggest parameterized routes. I'm not familiar enough with coffeescript, but here is a JS based example from a webapp I am working on:
ClientsApp.Router = Marionette.AppRouter.extend({
appRoutes: {
//...
"clients/:id/result/:resultID":"showReport",
//
}
});
var API = {
showReport: function(id, resultID){
ClientsApp.Show.Controller.showReport(id, resultID);
},
};
You can specify the parameters of whatever states drive the later modules, and Marionette knows how to pull the values (with a ':') from the route and pass them into the function. This would solve your rebuilding/passing values down to later views, while preventing the recursion/propagation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With