documentcloud/backbone — Issue #1083: Feature request: Backbone.history 'route' event args should provide named parameters
Author: hetsch
Created: 2012-03-09 11:11:07+00:00
State: open

It would be nice if the callback parameter args would provide an object similar than

```javascript
{
language: 'en',
entityId: '12'
}
```
A small example:

```javascript
Backbone.history.on('route', listener);

var listener = function(router, route, args) {
// comes in as array ['en', '12']
// here i have no idea that en == language or 12 == entityId
console.log(args);
// it would help if a structure like the above would be passed in
// { language: 'en', entityId: '12' }

}
```
I have an ugly workaround to map named parameters to their value

```javascript

// ...

initialize: function() {
Backbone.history.on('route', this._onRouteChanged, this);
},

_onRouteChanged: function() {
// save the current active route information
this._currActiveRoute = {
router: router,
route: route,
args: args
};

this._namedViewParams = null;

// SETTING THE CURRENTLY ACTIVE APPLICATION LANGUAGE
var lang = this.getNamedViewParam('language');
if(lang) {
this.language = lang;
this.trigger('languageChanged', lang);
}
},

getNamedViewParam : function(param) {
if(!this._namedViewParams) {
this._namedViewParams = this._resolveNamedViewParams(
this._currActiveRoute.router,
this._currActiveRoute.args
) || [];
}

var result = _.filter(this._namedViewParams, function(pair) {
if(pair[0] === param) {
return true;
}
});

// try returning the value
try {
return result[0][1]
} catch(e) {}
},

_resolveNamedViewParams: function(router, args) {
if(args.length > 0) {
var h = Backbone.history.handlers;
for(var i=0; i < h.length; i++) {
// find the actual route out of all (application wide) router routes
if(h[i].route.test(Backbone.history.fragment)) {
keys = _.keys(router.routes);
// find the route for this request out of all routes from the router
for(var j=0; j < keys.length; j++) {
if(h[i].route.test(keys[j])) {
// extract all named parameters out of route
if(matches = keys[j].match(/:\w+/g)) {
// strip : out of named parameters (need better regex)!
var cleaned = _.map(matches, function(param){ return param.replace(':', '')});
// combine args and named args
return _.zip(cleaned, args);
}
}
}
}
}
}
}

// ...
```

Hope someone else might be interested in that kind of functionality.
I haven't found an easier way to achieve this...