1717 * - Create application states (as defined by [[Ng2StateDeclaration]]).
1818 *
1919 * ```js
20- * export let state1 = {
20+ * export let state1: Ng2StateDeclaration = {
2121 * name: 'state1',
2222 * component: State1Component,
2323 * url: '/one'
2424 * }
2525 *
26- * export let state2 = {
26+ * export let state2: Ng2StateDeclaration = {
2727 * name: 'state2',
2828 * component: State2Component,
2929 * url: '/two'
3030 * }
3131 * ```
3232 *
33- * - Create application feature modules using [[UIRouterModule]]
33+ * - Import a [[UIRouterModule.forChild]] module into your feature `NgModule`s.
3434 *
3535 * ```js
36- * @ UIRouterModule({
37- * imports: [ CommonModule ],
38- * states: [ state1, state2 ]
36+ * @ NgModule({
37+ * imports: [
38+ * SharedModule,
39+ * UIRouterModule.forChild({ states: [state1, state2 ] })
40+ * ],
41+ * declarations: [
42+ * State1Component,
43+ * State2Component,
44+ * ]
3945 * })
4046 * export class MyFeatureModule {}
4147 * ```
4248 *
43- * - Optionally create a [[UIRouterConfig]] to perform any pre-bootstrap configuration.
49+ * - Import a [[UIRouterModule.forRoot]] module into your application root `NgModule`
50+ * - Either bootstrap a [[UIView]] component, or add a `<ui-view></ui-view>` viewport to your root component.
4451 *
4552 * ```js
46- * import {UIRouter} from "ui-router-ng2";
53+ * @ NgModule({
54+ * imports: [
55+ * BrowserModule,
56+ * UIRouterModule.forRoot({ states: [ homeState ] }),
57+ * MyFeatureModule,
58+ * ],
59+ * declarations: [
60+ * HomeComponent
61+ * ]
62+ * bootstrap: [ UIView ]
63+ * })
64+ * class RootAppModule {}
4765 *
48- * @ Injectable()
49- * export class MyUIRouterConfig {
50- * constructor() {} // Constructor is injectable
51- * configure(uiRouter: UIRouter) {
52- * uiRouter.urlRouterProvider.otherwise(() => uiRouter.stateService.target('home'));
53- * }
54- * }
66+ * browserPlatformDynamic.bootstrapModule(RootAppModule);
5567 * ```
5668 *
57- * - When bootstrapping the root module: use the [[provideUIRouter]] function:
58- * - Either bootstrap a [[UIView]] component, or add a `<ui-view></ui-view>` viewport to your root component.
69+ * - Optionally specify a configuration class [[ChildModule.configClass]] for any module
70+ * to perform any router configuration during bootstrap or lazyload.
71+ * Pass the class to [[UIRouterModule.forRoot]] or [[UIRouterModule.forChild]].
5972 *
6073 * ```js
61- * import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
62- * import {UIRouterModule, provideUIRouter, UIView} from "ui-router-ng2";
63- * import {MyUIRouterConfig} from "./router.config";
64- *
65- * @ UIRouterModule({
66- * import: [ FeatureModule, BrowserModule ],
67- * providers: [ provideUIRouter({ configClass: MyUIRouterConfig }) ],
68- * states: [ homeState ],
69- * bootstrap: [ UIView ]
70- * })
71- * class RootAppModule {}
74+ * import {UIRouter} from "ui-router-ng2";
7275 *
73- * platformBrowserDynamic().bootstrapModule(RootAppModule);
76+ * @ Injectable()
77+ * export class MyUIRouterConfig {
78+ * // Constructor is injectable
79+ * constructor(uiRouter: UIRouter) {
80+ * uiRouter.urlMatcherFactory.type('datetime', myDateTimeParamType);
81+ * }
82+ * }
7483 * ```
7584 *
7685 * @preferred @module ng2
7786 */ /** */
78- import { Injector , OpaqueToken , Provider } from "@angular/core" ;
79- import { ClassProvider , ExistingProvider , FactoryProvider , TypeProvider , ValueProvider } from "@angular/core" ; // has or is using
87+ import { Injector , Provider } from "@angular/core" ;
8088import { UIRouter } from "../router" ;
8189import { PathNode } from "../path/node" ;
8290import { StateRegistry } from "../state/stateRegistry" ;
@@ -88,24 +96,31 @@ import {ViewService} from "../view/view";
8896import { UIView , ParentUIViewInject } from "./directives/uiView" ;
8997import { ng2ViewsBuilder , Ng2ViewConfig } from "./statebuilders/views" ;
9098import { Ng2ViewDeclaration , NG2_INJECTOR_TOKEN } from "./interface" ;
91- import { UIRouterConfig } from "./uiRouterConfig" ;
99+ import { applyRootModuleConfig , applyModuleConfig } from "./uiRouterConfig" ;
92100import { Globals } from "../globals" ;
93101import { UIRouterLocation } from "./location" ;
94102import { services } from "../common/coreservices" ;
95103import { Resolvable } from "../resolve/resolvable" ;
96- import { ngModuleResolvablesBuilder } from "./statebuilders/lazyLoadNgModuleResolvable" ;
97- import { flattenR } from "../common/common" ;
98- import { UIROUTER_STATES_TOKEN } from "./uiRouterNgModule" ;
104+ import { RootModule , ChildModule , UIROUTER_ROOT_MODULE , UIROUTER_CHILD_MODULE } from "./uiRouterNgModule" ;
99105import { UIRouterRx } from "./rx" ;
100- import { LocationStrategy , HashLocationStrategy , PathLocationStrategy } from "@angular/common" ;
101106
102107/**
103108 * This is a factory function for a UIRouter instance
104109 *
105110 * Creates a UIRouter instance and configures it for Angular 2, then invokes router bootstrap.
106111 * This function is used as an Angular 2 `useFactory` Provider.
107112 */
108- let uiRouterFactory = ( routerConfig : UIRouterConfig , location : UIRouterLocation , injector : Injector ) => {
113+ let uiRouterFactory = (
114+ location : UIRouterLocation ,
115+ injector : Injector ) => {
116+
117+ let rootModules : RootModule [ ] = injector . get ( UIROUTER_ROOT_MODULE ) ;
118+ let childModules : ChildModule [ ] = injector . get ( UIROUTER_CHILD_MODULE ) ;
119+
120+ if ( rootModules . length !== 1 ) {
121+ throw new Error ( "Exactly one UIRouterModule.forRoot() should be in the bootstrapped app module's imports: []" ) ;
122+ }
123+
109124 // ----------------- Monkey Patches ----------------
110125 // Monkey patch the services.$injector to the ng2 Injector
111126 services . $injector . get = injector . get . bind ( injector ) ;
@@ -127,7 +142,6 @@ let uiRouterFactory = (routerConfig: UIRouterConfig, location: UIRouterLocation,
127142
128143 // Apply statebuilder decorator for ng2 NgModule registration
129144 registry . stateQueue . flush ( router . stateService ) ;
130- registry . decorator ( 'resolvables' , ngModuleResolvablesBuilder ) ;
131145
132146 // Prep the tree of NgModule by placing the root NgModule's Injector on the root state.
133147 let ng2InjectorResolvable = Resolvable . fromData ( NG2_INJECTOR_TOKEN , injector ) ;
@@ -139,13 +153,8 @@ let uiRouterFactory = (routerConfig: UIRouterConfig, location: UIRouterLocation,
139153 registry . stateQueue . autoFlush ( router . stateService ) ;
140154
141155 setTimeout ( ( ) => {
142- // Let the app apply custom configuration...
143- // (global transition hooks, deferIntercept, otherwise, etc)
144- routerConfig . configure ( router ) ;
145-
146- // Register the states from the root NgModule [[UIRouterModule]]
147- let states = injector . get ( UIROUTER_STATES_TOKEN , [ ] ) . reduce ( flattenR , [ ] ) ;
148- states . forEach ( state => registry . register ( state ) ) ;
156+ rootModules . forEach ( moduleConfig => applyRootModuleConfig ( router , injector , moduleConfig ) ) ;
157+ childModules . forEach ( moduleConfig => applyModuleConfig ( router , injector , moduleConfig ) ) ;
149158
150159 // Start monitoring the URL
151160 if ( ! router . urlRouterProvider . interceptDeferred ) {
@@ -158,55 +167,25 @@ let uiRouterFactory = (routerConfig: UIRouterConfig, location: UIRouterLocation,
158167} ;
159168
160169export const _UIROUTER_INSTANCE_PROVIDERS : Provider [ ] = [
161- { provide : UIRouter , useFactory : uiRouterFactory , deps : [ UIRouterConfig , UIRouterLocation , Injector ] } ,
170+ { provide : UIRouter , useFactory : uiRouterFactory , deps : [ UIRouterLocation , Injector ] } ,
162171 { provide : UIRouterLocation , useClass : UIRouterLocation } ,
172+ { provide : UIView . PARENT_INJECT , useFactory : ( r : StateRegistry ) => { return { fqn : null , context : r . root ( ) } as ParentUIViewInject } , deps : [ StateRegistry ] } ,
163173] ;
164174
165- export const _UIROUTER_PROVIDERS : Provider [ ] = [
175+ export const _UIROUTER_SERVICE_PROVIDERS : Provider [ ] = [
166176 { provide : StateService , useFactory : ( r : UIRouter ) => r . stateService , deps : [ UIRouter ] } ,
167177 { provide : TransitionService , useFactory : ( r : UIRouter ) => r . transitionService , deps : [ UIRouter ] } ,
168178 { provide : UrlMatcherFactory , useFactory : ( r : UIRouter ) => r . urlMatcherFactory , deps : [ UIRouter ] } ,
169179 { provide : UrlRouter , useFactory : ( r : UIRouter ) => r . urlRouter , deps : [ UIRouter ] } ,
170180 { provide : ViewService , useFactory : ( r : UIRouter ) => r . viewService , deps : [ UIRouter ] } ,
171181 { provide : StateRegistry , useFactory : ( r : UIRouter ) => r . stateRegistry , deps : [ UIRouter ] } ,
172182 { provide : Globals , useFactory : ( r : UIRouter ) => r . globals , deps : [ UIRouter ] } ,
173-
174- { provide : UIView . PARENT_INJECT , useFactory : ( r : StateRegistry ) => { return { fqn : null , context : r . root ( ) } as ParentUIViewInject } , deps : [ StateRegistry ] }
175183] ;
176184
177- /**
178- * Provides an Instance of UI-Router for NG2.
179- *
180- * Use this on the root NgModule to configure and create an instance of the Angular 2 UIRouter.
181- *
182- * @example
183- * ```js
184- *
185- * @ UIRouterModule({
186- * states: [ homeState, aboutState ],
187- * providers: [ provideUIRouter({ configClass: MyUIRouterConfig, useHash: true }) ],
188- * bootstrap: [ UIView ]
189- * }) class RootNgModule {}
190- *
191- * platformBrowserDynamic().bootstrapModule(RootNgModule);
192- * ```
193- *
194- * Note: UIRouter should only be provided *once*, on the root module, when bootstrapping the application.
195- */
196- export function provideUIRouter ( rootConfig : { configClass ?: typeof UIRouterConfig , useHash ?: boolean } = { } ) {
197- // Provide the UIRouter instance providers
198- return _UIROUTER_INSTANCE_PROVIDERS . concat (
199- // Provide the user-supplied UIRouterConfig class, or use base UIRouterConfig (as a no-op config)
200- { provide : UIRouterConfig , useClass : ( rootConfig . configClass as any || UIRouterConfig ) } ,
201- // Provide the PathLocationStrategy by default unless `useHash` is `true`
202- { provide : LocationStrategy , useClass : ( rootConfig . useHash ? HashLocationStrategy : PathLocationStrategy ) }
203- ) ;
204- }
205-
206185/**
207186 * The UI-Router providers, for use in your application bootstrap
208187 *
209- * @deprecated use [[UIRouterModule]] and [[provideUIRouter ]]
188+ * @deprecated use [[UIRouterModule.forRoot ]]
210189 */
211- export const UIROUTER_PROVIDERS : Provider [ ] = _UIROUTER_INSTANCE_PROVIDERS . concat ( _UIROUTER_PROVIDERS ) ;
190+ export const UIROUTER_PROVIDERS : Provider [ ] = _UIROUTER_INSTANCE_PROVIDERS . concat ( _UIROUTER_SERVICE_PROVIDERS ) ;
212191
0 commit comments