ExtJS 5.0 – Router Tweaks

Sencha

One of the coolest and most useful new tools included with ExtJS 5.0 is the app routing system. This is basically just some convenience methods around the already existing Ext.History module. In summmary it allows you to utilize the browser anchors (hash tags) to mimic page loads and lets you make use of the browser back and forward buttons. This comes in very handy when you wish to design a single page app.

Problems with stock implementation

If you are like me however, the out of the box implementation leaves a lot to be desired. I’m a bit OCD about certain things and I didn’t like some of the aspects of it.

  1. The default separator for multiple routes is |
    This really bugged me for some reason as I would greatly prefer / separated.
  2. On page reloads, it does not reload the last anchor
    This is an especially nasty one as it also affects any bookmarked links and when you load the page since you are technically on the hash even though it did not execute, you can not switch to the hash so any buttons that are there for that purpose will not work until you switch to a different hash and then back.
  3. After changing the separator, all the examples for passing variables in routes won’t work
    Since we are using the / as the separator all the provided examples in the API documentation will not work properly.

Solutions

The first issue is actually a very simple one to correct. It simply involved digging into a core ext file and locating a parameter that you can change to enable a different separator token. If you open up this file “/ext/src/app/route/Router.js” you will notice a variable named “multipleToken”.

Quite simply, change this to be something else. I preferred to change it in my App vs changing the ext source code. I put this line inside my Application.js launch method.

Ext.app.route.Router.multipleToken = "/";

See? super easy. Now for the next one, which is a little more involved.

If you navigate to a route in your app then you hit the browser refresh button you will notice your app reloads but does not fully go through the route. It won’t change tabs, etc (whatever your route is supposed to do).

The way I went about solving this was to save a state variable in the Application.js launch function if the token is defined on app launch, like so

var currentToken = Ext.History.getToken();
if (currentToken) {
Ext.state.Manager.set('lastPage', currentToken);
}

Now all that is left is placing some code somewhere in the controller of your main view that looks for that variable, resets it and then redirects you to the right hash. I put it in the afterrender method.

var lastPage = Ext.state.Manager.get('lastPage');
if (lastPage != null) {
Ext.getBody().mask("Loading last page...");
setTimeout(function() {
Ext.state.Manager.set('lastPage', null);
.app.redirectTo(lastPage, true);
Ext.getBody().unmask();
}, 2000);
}

One thing the above snippet requires is setting the appProperty variable in the Application.js file. Mine is like this

appProperty: 'app',

This allows you to get a reference to the main app object from anywhere in your code. like so “.app”

Now for the final issue. Since we are using the / as our separator, the examples provided in the ExtJS API documentation no longer work for passing variables through routes as they all utilize a / character. This one is actually pretty simple as well though. I simply started using a period instead to replace the / in those cases.

routes: {
'detail.:oprid': 'onUserDetail',
'permissions.:oprid': 'onUserPermissions'
},

Then the corresponding methods for these routes below

onUserDetail: function(oprid) {
},

onUserPermissions: function(oprid) {
},

That should get your routing system into something a little more user friendly as well as friendly on the eye.

Posted in Web Application Development Tagged with: , , , , , , , , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*