Question

I have multiple routers in my app, in general way it looks like this:

// Start backbone.js
if (!Backbone.History.started) {
    Backbone.history.start({pushState: true, hashChange: false});
}

// Perform some RPC requests ...

// Depending on user role, received from the server should be created suitable router:
var router;
if (typeof app.user.role === 'manager') {
    router = new routers.manager();
} else {
    router = new routers.guest();
}

Problem is that after page is loaded and script is executed routers do not do. anything. They do not load route for current url automatically. So, i had to fix it this way (i am not sure that it is a right way):

routers.guest.initialize = routers.manager.initialize = function() {
    var defaultRoute = 'default';
    if (typeof this.routes[Backbone.history.fragment] !== 'undefined') {
        this[this.routes[Backbone.history.fragment]]();
    } else {
        this.navigate(defaultRoute, true);
    }
};

It is working fine, except one bug: when i use route with params, for example /reset-password-confirm/:code - it is unable to find in in routes property. I could write some more code to fix it, but i suppose that i am doing something wrong, if i have to write such things - as i understand router should handle routes just after it was created.

So, questions:

  1. Why my router(s) does not handle routes for current url after it is being created? Perhaps i need to start backbone history later? (but this bug will happen again later then)

  2. How it is possible to make routes with params like /user/:id work there?

  3. Perhaps it is bad idea to re-create routers? Perhaps it is better to create all of them one time?

P.S. I've tried to create both routers and keep them, also i've trie to call backbone history start method after all routers were created.. but this didn't help :/

Was it helpful?

Solution

Assuming you route is declared as the following:

 routes : {
   '/user/:id' : 'user'
 }

Your initialize code is not working because when you initialize your router with a url such as: /user/1234. Backbone.history.fragment will be /user/1234 (not /user/:id). Since the this.routes object doesn't have a key of /user/1234, your else clause calls the default route.

If you first instantiate your router then call Backbone.history.start(), you will be able to remove your router initialize code. When you navigate to a url as /user/1234 your router will match the /user/:id route and call the user function.

The following should work for you without adding your initialize code:

var router = (app.user.role === 'manager') ? new routers.manager() 
                                           : new routers.guest();

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

OTHER TIPS

Looking at the code, seems like you're starting the backbone history before initializing any routes. That's most likely not goning to work.

The correct way of doing this type of seperation is by creating all the routes based on the role received from the server and then start the backbone history. Here's an SO thread that talks about it with code samples as well : How to protect routes for different user groups

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top