3

I'm stuck with a big backbone application.

It's running different applications within the main application. And we want to add the apps and also the routes asynchronously to the big app.

What I do now is to add the different apps asynchronously with Require.JS after the main apps is loaded. To add the new routes to the main routing I'm stop history and add the new routes and do a history start again. This works but, it has one major drawback. Every time I go to (app.navigate('x',true);) a new existing path fires the routing as many times I have history.started it. Also all the view render.

This slows the app down a lot and is totally inefficient.

Is there a way to dynamically add new routes without having to history.stop/start?

Cristiano Fontes
  • 4,920
  • 6
  • 43
  • 76
Toon Nelissen
  • 41
  • 1
  • 5

2 Answers2

3

You don't have to stop/start Backbone.history each time you add new routes, Backbone modifies its state when you call router.route or create a new router.

So, either manually add routes to your router:

var R = Backbone.Router.extend({
    routes: {
    }
});

var r = new R();
Backbone.history.start();

r.route('added', 'added', function() {
    console.log('added : '+window.location.hash);
});

or instantiate a new router

var R = Backbone.Router.extend({
  routes: {
  }
});

var r = new R();
Backbone.history.start();

var R2 = Backbone.Router.extend({
    routes: {
        'added': 'added'
    },
    added: function() {
        console.log('added: '+window.location.hash);
    }
});
var r2 = new R2();

and a demo

var R = Backbone.Router.extend({
  routes: {
    "help": "help"
  },
  help: function() {
      console.log('help : '+window.location.hash);
  }
});


var r = new R();
Backbone.history.start();
r.navigate('help', {trigger: true});


var R2 = Backbone.Router.extend({
  routes: {
    "r2": "r2"
  },
  r2: function() {
    console.log('r2 : '+window.location.hash);
  }
});
var r2 = new R2();
r2.navigate('r2', {trigger: true});


r.route('added', 'added', function() {
    console.log('added : '+window.location.hash);
});

r.navigate('added', {trigger: true});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>

<a href='#help'>help</a>
<a href='#r2'>r2</a>
<a href='#added'>added</a>
nikoshr
  • 32,926
  • 33
  • 91
  • 105
0

I wrote a little .js file that has a router. It should be useable for different purposes, so you can pass desired callback (routes) on init. The init takes a parameter routes (an array), which holdes the following info:

routeId:"book/:id",
routeName:"routeBooks",
routeCallback: $.proxy(function(id){ 
 // $.proxy() is a jQuery function that ensures you call the callback in the right context
      // do fandy stuff here.
})

To parse the routes, I use the following:

for( route in routes ){
    routesFromConfig[routes[route].routeId.toString()] = routes[route].routeName;
}
var ModalRouter = Backbone.Router.extend({
    routes:routesFromConfig
});
router = new ModalRouter();
for( route in routes ){
    // test if the callback is a function
    if(_.isFunction(routes[route].routeCallback)){
        router.on('route:'+routes[route].routeName.toString(), routes[route].routeCallback);
    }
}

Backbone.history.start();

I hope this helps to set up a router from routes passed from another place in your app

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
MJB
  • 3,934
  • 10
  • 48
  • 72