crossroads.js
crossroads.js copied to clipboard
ideas for a v2.0 release
Some ideas/improvements for a future not backwards compatible release:
no global/static router
So instead of having access to a global crossroads router you would need to
create your own instance. I think this would encourage people to create their
own instances and not rely on a global object.
// instead of
crossroads.addRoute(...);
// you would need to create a new instance
var myRouter = crossroads.create();
myRouter.addRoute(...);
see: #55 and #19
remove "greedy" routes support
As discussed before I think this feature is unnecessary when you have option to pipe multiple routers and I think it was a very bad design decision.
see: #68
Route ID + no listener on addRoute()
Some people asked for a way to retrieve a route by their ID so they could use
Router#interpolate() more easily through the app.
So far I haven't needed this feature (since I usually code something similar inside my app structure) but it might make things simpler to some users. Thinking in something like:
// notice that there is no way to set a listener directly you need to
// use the "matched" signal.
var newsRoute = myRouter.addRoute('news', 'news/{id}', priority);
newsRoute.matched.add(doSomething);
// later you can retrieve the route
var path = myRouter.getRoute('news').interpolate({id:123});
// and also simplify removal
myRouter.removeRoute('news');
I think it will make it clearer that the signal can have multiple listeners.
Maybe ID can be optional, so if user doesn't provide it the router uses the pattern as the ID instead:
router.addRoute('foo/{bar}');
router.getRoute('foo/{bar}').interpolate({id:123});
see: #38
Remove typecasting or make it a local setting
There are many cases where it can cause conflicts since you don't expect it to happen on a few cases. I think all values should be treated as strings and user can typecast the value inside his own app.
See: #81 and mout/string/typecast
Add route.trigger()
Basically the same as calling myRouter.parse( route.interpolate({id:123}) )
just as a convenince.
drop strict/legacy slash behavior
the default behavior nowadays is loose which I think will be better for most users since it avoids dumb mistakes, haven't seen any case where the other behaviors are a requirement. (see #35)
route groups and filters
I'm using Laravel 4 on my current project and route groups + filters are very useful for handling any kind of logic that should happen before the route action is triggered.
My main concern with it is that since most actions in JavaScript are asynchronous we might get into weird race conditions (multiple route changes triggered while the first filter is still executing). It's hard to decide what would be the correct behavior - maybe each route and filter should have the option to expose a cancel() method as well...
async routing
sometimes user might need to load some Ajax data or do some async operation to validate a route, maybe that is something we should support. - Will increase complexity drastically.
only normalize fragments as object + pass route/router as argument on handler
It was a bad design decision to allow multiple arguments on the route handler, it makes things harder than needed and motivates poor code. I think the best solution would be to default the normalize to object and pass route (and/or router) to handler as well to increase flexibility.
I think second argument could be an object with lots of info about the current request + route + custom data. I did a similar abstraction (on top of crossroads) for a project and it worked really well.
var fooRoute = router.addRoute('{foo}/:bar:');
fooRoute.matched.add(function(info, args){
// info = { route, request, router, data, ... }
console.log( info.route.interpolate( args ) );
});
some sort of pre-filter for fragments that happens before normalize_
That way we can set a shared behavior globally and use it only to process the property values.
route.rules.pre_ = function(request, values){
values.foo = values.bar === 'baz'? 'foo-bar' : 'foo';
return values;
}
};
@millermedeiros the ideas you described above, did you discard them? To be honest I'm very interesting in the correct filters support. Now, I use matched/switched for that but they have no any cancel() logic
@killmenot I never got the time to work on this, I started working inside bigger projects and mostly maintaining legacy apps.. the last time I used crossroads on any project was back in 2013, so that's why the development/support here been stale ever since. - I was mostly developing new features and fixing bugs as needed...