Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone router won't fire events

I have some navigation links on the dom when the app is started which I wish to hijack for progressive enhancement via Backbone (theres a very static text content version underlying the backbone app).

The html looks like this:

...
<body>
<header>
<nav>
<ol>
<li>
<a href="/en/home">home</a>
</li>
<li>
... few more links
</header>

Then my App is instantiated using:

var App = (function(fw){
 var $      = fw;
 var workspace            = {};
 var self     = {};
 var lang     = "en";
 var models     = {...};
 var views     = {...};
 var collections   = {...};
 self.init = function() {
  workspace = new Workspace(
  {
    routes: {
     "/": "home",
     "/home": "home",
     "/terms": "terms",
     "/news": "blog"
   },
    lang : lang
  })
 }
 return self;
});
var app;
// launch
$(document).ready(function() {
 app = new App(jQuery);
 app.init();
});

The workspace is just a router and those routes from the app are correctly processed into the router via the initialize function, also the links work and change the URL as expected and do it with hashes on older browsers. The problem is that no callbacks are ever made within the Router/Workspace itself. It's simply mute and doesnt fire the functions when the clicks are made

Here's my Workspace/Router:

var Workspace = Backbone.Router.extend({

 routes : {},
 //functions                     <------------THESE
 home:    function(e){
  e.preventDefault();
  console.log("home here");
  App.views.HomeView.render();
 },
 terms:    function(){          //<-----------NEVER
  console.log("terms here");
  App.views.TermsView.render();
 },
 blog:    function(){           //<-----------FIRE
  console.log("blog here");
 },
 initialize:  function(params){
  var t = this;
  var tmpr = {};
  for(var i in params.routes)
  {
    //this just fuses lang and each route so /home becomes /en/home 
                  tmpr["/"+params.lang+i] = params.routes[i];
  }
  this.routes = tmpr; // this is fine and when logged it shows nicely with all routes looking good
  // router will only ever initialize once so lets deal with the stuff currently on the DOM before the app is inited.
  $("a",$("header")).click(function(e){
   e.preventDefault();
   Backbone.history.navigate($(this).attr("href"),true);//<-- true is set? should fire methods?
   // I've also tried all kinds of variations like t.navigate(..) where t is this workspace
  });
//this also seems to be fine and either does hashes or states
  if(history && history.pushState) {
   Backbone.history.start({
    pushState : true
   });
   console.log("has pushstate");
  } else {
   Backbone.history.start();
   console.log("no pushstate");
  }
  console.log("Router inited with routes:",this.routes);//logs routes nicely
 }
});
like image 406
Alex Avatar asked Nov 14 '11 13:11

Alex


1 Answers

The routes have already been bound when the initialize function is run (see the backbone source).

You can trigger the routes binding with the _bindRoutes function:

this.routes = tmpr;
this._bindRoutes();
like image 93
Benoit Garret Avatar answered Oct 10 '22 11:10

Benoit Garret