< >

Marionette.AppRouter

The Marionette AppRouter extends the Backbone.Router to
make it easier to construct a large number of routes for your app. This is
particularly useful if you want to build a large single-page app while keeping
your router's core logic readable.

Documentation Index

Using the AppRouter

The Marionette AppRouter is typically used to set up your app when the user
loads a specific endpoint directly. Typically, in a single-page app, users will
expect to be able to easily navigate back to a section of the application by
bookmarking a URL and loading it directly. Let's look at a concrete example:

var Mn = require('backbone.marionette');

var EmailController = {
  showEmail: function(email) {
    // Look up the email and display it in our main layout
  }
};

var EmailRouter = Mn.AppRouter.extend({
  controller: EmailController,

  appRoutes: {
    'emails/:email': 'showEmail'
  }
});

Assuming our application is served from the root, whenever the user accesses
http://ourapplication.com/#emails/email-subject-line-123, the method
showEmail will be called with email-subject-line-123 as its argument. This
will be covered in more detail below.

Configure Routes

The AppRouter uses the appRoutes option to define how we respond to routes
being accessed. To define routes, set the route as your key and the method to
call as a string referencing a method on your controller. For more information
on route definitions, see the [Backbone documentation][#backbone-routes].

The major difference between appRoutes and routes is that we provide
callbacks on a controller instead of directly on the router itself. This allows
you to define a simpler router and keep your controller logic closer to the
modules it interacts directly with:

var Mn = require('backbone.marionette');
var EmailController = require('./emails/controller/email');

var MyRouter = Mn.AppRouter.extend({
  controller: EmailController,

  // "someMethod" must exist at controller.someMethod
  appRoutes: {
    'email': 'listEmails',
    'email/:email': 'showEmail'
  }
});

As the AppRouter extends Backbone.Router, you can also define a routes
attribute whose callbacks must be present on the AppRouter:

var Mn = require('backbone.marionette');

var MyRouter = Mn.AppRouter.extend({
  routes: {
    'email/:email': 'showEmail'
  },

  showEmail: function(email) {
    // show the email
  }
})

See the Backbone documentation for more information about
defining routes.

Configure Routes In Constructor

If you want more control when managing your routes, you can define your routes
on router instantiation:

var Mn = require('backbone.marionette');
var EmailController = require('./emails/controllers/email');

var MyRouter = new Mn.AppRouter({
  controller: EmailController,
  appRoutes: {
    'email/': 'listEmails',
    'email/:email': 'showEmail'
  }
});

Add Routes At Runtime

In addition to setting the appRoutes for an AppRouter, you can add app routes
at runtime, to an instance of a router. This is done with the appRoute()
method call. It works the same as the built-in router.route() call from
Backbone's Router, but has all the same semantics and behavior of the
appRoutes configuration.

var Mn = require('backbone.marionette');

var MyRouter = Mn.AppRouter.extend({});

var router = new MyRouter();
router.appRoute("/foo", "fooThat");

Also you can specify a controller with the multiple routes at runtime with the
processAppRoutes method. This will preserve the existing controller as well:

var Mn = require('backbone.marionette');

var MyRouter = Mn.AppRouter.extend({});

var router = new MyRouter();
router.processAppRoutes(myController, {
  "foo": "doFoo",
  "bar/:id": "doBar"
});

Specify A Controller

App routers can only use one controller object. You can either specify this
directly in the router definition:

var Mn = require('backbone.marionette');

var someController = {
  someMethod: function(){ /*...*/ }
};

Mn.AppRouter.extend({
  controller: someController
});

The object that is used as the controller has no requirements, other than it
will contain the methods that you specified in the appRoutes.

Using Marionette.Object

A controller can also be an instance of
Marionette.Object - this is useful for cases where
you want to access the helper tools of the Object API and pass through
information on instantiation.

Multiple Routers

Marionette allows you to run multiple AppRouters in a single application. It's
recommended that you break your routing into multiple sections, each with its
own router and/or controller setting up the views for their own components. This
will make it much easier to find and manage your route-handling logic as your
application grows in complexity.

Backbone History

The Backbone History API monitors the browser's location bar
and triggers route changes on your app routers. It also provides a set of
methods to change the contents of the location bar manually when you want to
expose functionality to your user via a URL:

var Bb = require('backbone');
var Mn = require('backbone.marionette');

var EmailView = require('./email/views/email');

var EmailList = Mn.View.extend({
  regions: {
    layout: '.layout-hook'
  },

  showEmail: function(model) {
    this.showChildView('layout', new EmailView({model: model}));
    Bb.history.navigate('email/' + model.id);
  }
});

As stated in the Backbone documentation, navigate takes an options argument
that lets you trigger on route change. We recommend against using this as it
tends to cause side-effects like making it hard to ensure the route is only
navigated to once, or unintentionally firing different route changes.

Handling Route Changes

When the user navigates to a new route in your application that matches a route
in your AppRouter, the route event will be fired. Listening to this will let
you perform extra custom behavior:

var Mn = require('backbone.marionette');
var Controller = require('./email/controller');

var MyRouter = Mn.AppRouter.extend({
  controller: Controller,

  appRoutes: {
    'emails/:email': 'showEmail'
  },

  onRoute: function(name, path, args) {
    console.log('User navigated to ' + path);
  }
});

This event handler takes three arguments:

  1. name - Name of the route
  2. path - Path that triggered this event
  3. args - Arguments passed into the route
Improve this page