Description
We're currently writing a fairly large web application with Angular 1.2-rc2 and UI-Router. We've come into contact with an issue that is a bit problematic for using ui-router. Most of our routes have their own modules because they contain quick a bit of functionality and it's easier to separate concerns, but the problem we've encountered is when you have a parent module that's dependent on a child module, where in this child module it's state parent is the original module. This would cause an error because the parent state hasn't been instantiated yet because it's still waiting for it's dependencies.
Here's an example of what I mean, this is how ui-router should function (as per the example in the docs):
angular.module('spaces', [ 'ui.router'])
.config(function ($stateProvider)
{
$stateProvider
.state('spaces', {
url: '/spaces'
});
});
angular.module('spaces.details', ['spaces', 'ui.router'])
.config(function ($stateProvider)
{
$stateProvider.state('spaces.details',
{
url: '/{id:[0-9]{1,12}}'
});
});
The problem here is that the config of 'spaces.details' will never run unless something is dependent on it. In this app, you get to 'spaces.details' from 'spaces' which isn't a dependency per say, so our only way to actually get the config function of 'spaces.details' to run is to add that dependency to 'spaces' since it would seem like the logical place, like this:
angular.module('spaces', ['spaces.details', 'ui.router'])
.config(function ($stateProvider)
{
$stateProvider
.state('spaces', {
url: '/spaces'
});
});
angular.module('spaces.details', [ 'ui.router'])
.config(function ($stateProvider)
{
$stateProvider.state('spaces.details',
{
url: '/{id:[0-9]{1,12}}'
});
});
That looks all good, but now there will be an error running it saying that 'spaces.details' route doesn't have a parent because the 'spaces.details' config function ran before it's parent ('spaces'). This circular problem is really annoying. The solution we have for now is to have all modules using ui-router to be a dependency of our main app.js file, which in turn runs all configs for every module and sets the routing properly. Furthermore, I find it annoying that the dependency model is backwards, in this case, 'spaces.details' is dependent on 'spaces' and it's data, not the other way around, which would cause confusion.
My proposed solution to this is to add a new function that can be attached after the module definition that specifies the routes and is ran the second the module is defined. Something along these lines:
angular.module('spaces', [ 'ui.router'])
.state('spaces', {
url: '/spaces',
controller: 'SpacesCtrl',
templateUrl: 'spaces/spaces.tpl.html'
});
angular.module('spaces.details', ['spaces', 'ui.router'])
.state('spaces.details', {
url: '/{id:[0-9]{1,12}}',
controller: 'SpacesDetailsCtrl',
templateUrl: 'spaces/spaces-details.tpl.html'
});
And the order in which the state is called is pretty much a non issue as long as the code either adds a placeholder until the parent is defined or that if the parent is missing that it would find it before continuing the route definition.
That's about it, sorry about it being long, I was just trying to think out loud. I'd love to hear about opinions and suggestions on this. If nobody has an objection, I might try to get this working myself and do a PR when it's complete.