-
Notifications
You must be signed in to change notification settings - Fork 138
Description
We want to support multilingual urls and hence we want to defer the url to state binding to be done at runtime rather than being performed statically. Imagine we have a sitemap service which retrieves the urls per states e.g.:
{
'en': [
{'module': 'app.home', 'path': ''},
{'module': 'app.about', 'path': '/about'},
],
'sv': [
{'module': 'app.home', 'path': ''},
{'module': 'app.about', 'path': '/om'}
]
}
we want to wire the state app.home
and app.about
to /en
and /en/about
when the language is en
and '/sv' and '/sv/om' when the language is '/sv'.
Looking at UIRouter.forRoot
or UIRouter.forChild
there is a options.config
which could allow us to enable this behaviour which is called from the applyModuleConfig
method:
function applyModuleConfig(uiRouter, injector, options) {
if (options === void 0) { options = {}; }
if (isFunction(options.config)) {
options.config(uiRouter, injector);
}
var states = options.states || [];
states.forEach(function (state) { return uiRouter.stateRegistry.register(state); });
}
What is stopping us from using this hook is the fact that options.config
only takes uiRouter
and injector
as arguments.
Adding options
(module) as a third parameter will allow us to achieve deferred route configuration.
export function applyModuleConfig(uiRouter: UIRouter, injector: Injector, options: StatesModule = {}) {
if (isFunction(options.config)) {
options.config(uiRouter, injector, options);
}
let states = options.states || [];
states.forEach(state => uiRouter.stateRegistry.register(state));
}
Example
As an example of how this would work have a look at the ui-router-multilingual project
To run the project:
npm install
npm start.deving
Open the browser and goto http://localhost:5555/en and hover on the links HOME and ABOUT.
- HOME should point to /en/
- ABOUT should point to /en/about
Open the browser and goto http://localhost:5555/sv and hover on the links HOME and ABOUT.
- HOME should point to /sv/
- ABOUT should point to /sv/om
Opening directly the link http://localhost:5555/ will default to english.
To configure multilingual modules we would setup the forChild
and forRoot
we would add the uiRouterConfigureSitemap
config function e.g.
@NgModule({
imports: [CommonModule,
UIRouterModule.forChild({
states:CHILD_STATES,
config: uiRouterConfigureSitemap
})],
declarations: [AboutComponent],
exports: [AboutComponent]
})
export class AboutModule {
}
The config function is simple:
export function uiRouterConfigureSitemap(router: UIRouter, injector: Injector, module: StatesModule) {
let states: ExtNg2StateDeclaration[] = <ExtNg2StateDeclaration[]>module.states;
// Process the states;
let filteredStates: ExtNg2StateDeclaration[] = _.filter(states, (s) => {
return s.future && !s._complete
});
_.map(filteredStates, (s) => {
let sitemapObj:any = _.find(getSitemap(), (sitemap:any) => sitemap.module == s.name);
console.log(`Retrieved ${s.name} from sitemap ${sitemapObj.path}`);
// Set the url from the sitemap object
s.url = sitemapObj.path;
s._complete = true;
});
router.urlService.config.strictMode(false);
}
Note that ui-router-ng2 is committed. node_modules/ui-router-ng2
includes the changes proposed in the Pull Request.