Evan Emolo
Evan Emolo

Reputation: 1670

Backbone.js router navigation going to incorrect route

I am having trouble navigating to different routes with a navbar via Backbone. Clicking on #logo and #home properly sends me to index. However clicking on #demo also sends me to index instead of the demo route. Why?

navbar.js

var HeaderNavView = Backbone.View.extend({
  tagName: 'div',

  template: _.template( HeaderNavTemplate ),

  events: {
    'click #logo': 'goToIndex',
    'click #home': 'goToIndex',
    'click #demo': 'goToDemo'
  },

  render: function() {
    var template = this.template();
    this.$el.html(template);
    return this;
  },

  goToIndex: function() {
    console.log('go to index');
    IndexRouter = new Backbone.Router();
    var route = '';
    IndexRouter.navigate(route, {trigger: true});
  },

  goToDemo: function() {
    console.log('header nav to demo route')
    demoRouter = new Backbone.Router();
    var route = 'demo';
    demoRouter.navigate(route, {trigger: true});
  }
});

routes.js

Router = Backbone.Router.extend({
  routes: {
    '': 'index',
    'demo': 'demo'
  },

  index: function() {

    $('#videoIndex').append( IndexTemplate )
    var headerNavView = new HeaderNavView;
    $('#indexHeaderNav').append( headerNavView.render().el );

    ...additional nested views
  },

  demo: function() {

    $('#demoDetails').append( DemoTemplate );

    ...additional nested views
  } 
});    

Upvotes: 0

Views: 1517

Answers (1)

Nick Tomlin
Nick Tomlin

Reputation: 29221

I don't want simplify your routing to much, but why are you creating a new router to navigate to /demo?

 goToDemo: function() {
    console.log('header nav to demo route')
    demoRouter = new Backbone.Router();
    var route = '/demo';
    demoRouter.navigate(route, {trigger: true});
  }

Could be simplified as:

goToDemo: function() {
  Backbone.history.navigate('demo', {trigger: true});
}

Another way of going about this would be to create a catch all event listener for links, that would navigate to backbone routes specified by "local" anchors:

// stolen from: http://stackoverflow.com/questions/7640362/preventing-full-page-reload-on-       backbone-pushstate
$(document).on('click', 'a:not([data-bypass])', function (evt) {
   var href = $(this).attr('href');
   var protocol = this.protocol + '//';

   if (href.slice(protocol.length) !== protocol) {
     evt.preventDefault();
     Backbone.history.navigate(href, true);
   }
});

This way your view does not need to handle navigating to individual routes. You can just include a tags in your view's template (or any view's template) and have Backbone take over.

an aside

As it currently stands, your goToDemo function does not use the Router you are creating in routes.js. Typically you would initialize this router outside of your individual scripts (tied to a global like app) and then use it to navigate. Instantiating a router on a single route is not the best way to go about this IMHO.

Upvotes: 2

Related Questions