Skip to content

Ecce Signum

Immanentize the Empathy

  • Home
  • About Me
  • Published Works and Literary Matters
  • Indexes
  • Laboratory

Day: May 2, 2014

Simple Backbone Marionette Example With AppRouter

2014-05-02 John Winkelman

This one took a little longer than the rest to put together, because I nearly broke my brain trying to figure out how routing worked. I found myriad code samples for setting up and using the router, but no one sample had everything I needed to put together a bare-bones app. Once i finally figured it out, the rest snapped together immediately. So without further ado – First, the Javascript file:

/* define the application */
var app = new Backbone.Marionette.Application();

/* add the main region to the application */
app.addRegions({
	appRegion: '#AppBase'
});

/* define the module we will be using to create this app */
app.module('RouteTest',function(module, App, Backbone, Marionette, $, _){
	"use strict";

	/* the layout for the main view */
	module.AppLayoutView = Marionette.LayoutView.extend({
		tagName: 'div',
		id: 'AppLayoutView',
		template: '#template-AppLayoutView',

		regions: {
			'contentRegion' : '#ContentRegion'
		},
		ui: {
			'navHome' : '#nav-home',
			'navInfo' : '#nav-info'
		},
		events: {
			'click #nav-home' : 'onNavHomeClicked',
			'click #nav-info' : 'onNavInfoClicked'
		},

		/* when the view initializes, call initRouter to */
		initialize: function() {
			this.initRouter();
		},

		/* once the DOM is ready, start the Backbone history manager.
			This will cause the application to synch up with the 
			current route of the browser, e.g. #home or #info.
			This must be called onRender instead of on initialize
			because it immediately tries to render the appropriate view
			into the contentRegion. Also: If you don't start the backbone
			history, the router won't work. */
		onRender: function() {
			if( ! Backbone.History.started) Backbone.history.start();
		},

		/* initialize the AppRouter, which synchs the application
			to the browser navigation */
		initRouter: function() {

			// cache reference to 'this' in the module scope
			var capturedThis = this;

			// assign route handlers to specific routes.
			// In this case, 'home' is triggered when the browser
			// visits index.html#home. Likewise index.html#info.
			// the empty set is for an address with no hash.
			var appRouteHandler = {
					'' : 'onHomeRoute',
				'home' : 'onHomeRoute',
				'info' : 'onInfoRoute'
			}

			// controller which contains the methods which
			// are used as route handlers. These are referenced
			// in the appRoutes object above.
			var appRouterController = {
				onHomeRoute: function() {
					capturedThis.onHomeNavigated();
				},
				onInfoRoute: function() {
					capturedThis.onInfoNavigated();
				}
			};

			// define an AppRouter constructor
			var router = Marionette.AppRouter.extend({});

			// create a new instance of the AppRouter
			// and assign the routes and controller
			var appRouter = new router({
				appRoutes: appRouteHandler, 
				controller: appRouterController
			});
		},

		/* called when the router sees that we have met the criteria
			to trigger the 'onHomeRoute' handler */
		onHomeNavigated: function() {

			// define and display an instance of the HomeLayoutView
			var homeLayoutView = new module.HomeLayoutView();
			this.contentRegion.show(homeLayoutView);

			// update the navigation
			this.$el.find('.navButton.active').removeClass('active');
			this.ui.navHome.addClass('active');
		},

		/* called when the router sees that we have met the criteria
			to trigger the 'onInfoRoute' handler */
		onInfoNavigated: function() {
			var infoLayoutView = new module.InfoLayoutView();
			this.contentRegion.show(infoLayoutView);
			this.$el.find('.navButton.active').removeClass('active');
			this.ui.navInfo.addClass('active');
		}
	});

	/* view definition for the 'Home' screen */
	module.HomeLayoutView = Marionette.LayoutView.extend({
		tagName: 'div',
		id: 'HomeLayoutView',
		className: 'contentLayout',
		template: '#template-HomeLayoutView'
	});

	/* view definition for the 'Info' screen */
	module.InfoLayoutView = Marionette.LayoutView.extend({
		tagName: 'div',
		id: 'InfoLayoutView',
		className: 'contentLayout',
		template: '#template-InfoLayoutView'
	});

	/* add initializer, which fires when the app starts */
	module.addInitializer(function(){
		var layout = new module.AppLayoutView();

		/* show the layout in the region we created at the top of this file */
		app.appRegion.show(layout);
	});
});

/* when the DOM for this page is available, start the application */
$(document).ready(function() {
	app.start();
});

And here is the HTML file, including the templates.

<!doctype html>
<html>
	<head>
		<title>Backbone/Marionette Routing Example Using AppRouter</title>
		<style type="text/css">
			body {
				background: #ffffff;
			}
			#AppBase {
				width: 600px;
				margin: 10px auto;
				padding: 0;
			}
			#AppLayoutView {
				float: left;
				width: 598px;
				margin: 0;
				padding: 0;
				border: 1px solid #808080;
			}
			h1 {
				margin: 0;
				padding: 0;
				float: left;
				width: 100%;
				height: 30px;
				text-align: center;
				font: 24px/30px courier;
			}
			#Navigation {
				float: left;
				width: 100%;
				height: 30px;
				background: #ededed;
				text-align: center;
			}
			#Navigation a {
				font: 16px/30px courier, monospace;
				color: #000000;
				text-decoration: none;
			}
			#Navigation .navButton.active {
				color: #ff0000;
			}
			#ContentRegion {
				float: left;
				width: 100%;
			}
			.contentLayout {
				float:left;
				width: 100%;
				margin: 0;
				padding: 0;
				
			}
			#HomeLayoutView {
				background: #edffed;
			}
			#InfoLayoutView {
				background: #ededff;
			}
			.contentLayout h2 {
				margin: 0;
				padding: 0;
				text-align: center;
				border-bottom: 1px solid #808080;
				background: #ffffff;
			}
			.contentLayout p {
				padding: .5em 1em;
			}
		</style>
	</head>
	<body>
		<!-- Base element for app -->
		<div id="AppBase"></div>

		<!-- main layout template -->
		<script type="text/template" id="template-AppLayoutView">
			<h1>Backbone/Marionette Routing Example</h1>
			<div id="Navigation">
				<a id="nav-home" class="navButton" href="#home">Home</a> : : : 
				<a id="nav-info" class="navButton" href="#info">Information</a>
			</div>
			<div id="ContentRegion">HELLO!</div>
		</script>

		<!-- home screen template -->
		<script type="text/template" id="template-HomeLayoutView">
			<h2>Home</h2>
			<p>This is the home view</p>
		</script>

		<!-- info screen template -->
		<script type="text/template" id="template-InfoLayoutView">
			<h2>Information</h2>
			<p>This is a page of information</p>
		</script>

		<!-- libraries -->
		<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
		<script type="text/javascript" src="js/underscore.js"></script>
		<script type="text/javascript" src="js/backbone.js"></script>
		<script type="text/javascript" src="js/backbone.marionette.js"></script>

		<!-- app code -->
		<script type="text/javascript" src="js/script.js"></script>
	</body>
</html>

By the way, the missing piece which ended up costing me the better part of a day was the Backbone.history.start() call in the onRender method in the main Layout view.

Posted in Programming comment on Simple Backbone Marionette Example With AppRouter

Personal website of
John Winkelman

John Winkelman in a diner in San Francisco

Archives

Categories

Posts By Month

May 2014
S M T W T F S
 123
45678910
11121314151617
18192021222324
25262728293031
« Apr   Jan »

Twitter Feed

Retweet on TwitterJohn Winkelman Retweeted
weirdlilguyscats being weird little guys@weirdlilguys·
27 Jun

Hi everyone - taking some time off to mourn the loss of half the country’s rights and status as free citizens in America.

Please do what you can to support groups helping those that will now need to travel for reproductive care, like the @BrigidAlliance
https://brigidalliance.org/donate/

Reply on Twitter 1541407247175229442Retweet on Twitter 1541407247175229442405Like on Twitter 15414072471752294424514Twitter 1541407247175229442
JohnWinkelmanJohn Winkelman@JohnWinkelman·
26 Jun

4 of 5 stars to The Memory Librarian by Janelle Monáe https://www.goodreads.com/review/show?id=4790331558

Reply on Twitter 1541143905177067521Retweet on Twitter 1541143905177067521Like on Twitter 1541143905177067521Twitter 1541143905177067521
Retweet on TwitterJohn Winkelman Retweeted
GennHutchisonGennifer Hutchison@GennHutchison·
20 Jun

Talking to someone about an estranged adult child and their parent, and the person could not understand the child cutting the parent off because "if they die, wouldn't you feel terrible you never made peace?" And it's interesting because... (cont'd)

Reply on Twitter 1539034762790113280Retweet on Twitter 15390347627901132801458Like on Twitter 15390347627901132808061Twitter 1539034762790113280
Load More...

Links of Note

Reading, Writing
Tor.com
Locus Online
The Believer
File 770
IWSG

Watching, Listening
WYCE Electric Poetry
Writing Excuses Podcast
Our Opinions Are Correct

News, Politics, Economics
Naked Capitalism
Crooked Timber

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

© 2022 Ecce Signum

Proudly powered by WordPress | Theme: x-blog by wpthemespace.com