Search code examples
javascriptbackbone.jsmarionettebackbone-routing

Having trouble with Marionette JS router


I am having a trouble with my router and controller. On my app's before:start, I have a handler that fetches collections of Leads and Vehicles.

I have a single region, with my layout view as:

var App = new Marionette.Application({});

var AppLayoutView = Marionette.LayoutView.extend({
  el: 'body',
  regions: {
    main: '#app-container'
  }
});

My controller is:

var Controller = Marionette.Object.extend({
    leads: function() {
      App.regions.main.show(new App.leadsTableView({collection: App.leads}));
    },
    vehicles: function() {
      App.regions.main.show(new App.vehiclesTableView({collection: App.vehicles}));
    }
});

In my start handler:

App.on('start', function() {
  App.regions = new AppLayoutView();
  App.router = new Marionette.AppRouter({
    controller: new Controller(),
    appRoutes: {
      'leads': 'leads',
      'vehicles': 'vehicles'
    }
  });

  Backbone.history.start({pushState: true});
});

App.start();

How can I start with a specific route? And, when a user goes to #vehicles, how can I make the region load the new view? I'm missing something about routers.

EDIT: When I go to, #leads in my URL, my vehicles view comes up. When I click on links that go to #leads and #vehicles, they don't work.


Solution

  • Default route

    You can define a default by adding a "splat" route (one that starts with *) to the end of your routes. I like to use *default to make the intent obvious:

    appRoutes: {
      'leads': 'leads',
      'vehicles': 'vehicles',
      '*default': 'leads'
    }
    

    Broken links

    Because you are using pushstate routing, the view URL is /vehicles rather than the hash fragment #vehicles. You should no longer use hash fragment urls.

    Here's a simple approach to trigger pushState routes with link clicks:

    $('a[href]').on('click', function(e) {
      e.preventDefault();
      var href = e.target.getAttribute('href');
      App.router.navigate(href, { trigger: true })
    });
    

    You may find this post about moving from hash fragment to pushState routing useful.

    You'll also need to configure your server to pass requests that match your route to the main app page - for example, it needs to understand that http://localhost/app/vehicle should be handled by http://localhost/app.