17
17
* - Create application states (as defined by [[Ng2StateDeclaration]]).
18
18
*
19
19
* ```js
20
- * export let state1 = {
20
+ * export let state1: Ng2StateDeclaration = {
21
21
* name: 'state1',
22
22
* component: State1Component,
23
23
* url: '/one'
24
24
* }
25
25
*
26
- * export let state2 = {
26
+ * export let state2: Ng2StateDeclaration = {
27
27
* name: 'state2',
28
28
* component: State2Component,
29
29
* url: '/two'
30
30
* }
31
31
* ```
32
32
*
33
- * - Create application feature modules using [[UIRouterModule]]
33
+ * - Import a [[UIRouterModule.forChild]] module into your feature `NgModule`s.
34
34
*
35
35
* ```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
+ * ]
39
45
* })
40
46
* export class MyFeatureModule {}
41
47
* ```
42
48
*
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.
44
51
*
45
52
* ```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 {}
47
65
*
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);
55
67
* ```
56
68
*
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]].
59
72
*
60
73
* ```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";
72
75
*
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
+ * }
74
83
* ```
75
84
*
76
85
* @preferred @module ng2
77
86
*/ /** */
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" ;
80
88
import { UIRouter } from "../router" ;
81
89
import { PathNode } from "../path/node" ;
82
90
import { StateRegistry } from "../state/stateRegistry" ;
@@ -88,24 +96,31 @@ import {ViewService} from "../view/view";
88
96
import { UIView , ParentUIViewInject } from "./directives/uiView" ;
89
97
import { ng2ViewsBuilder , Ng2ViewConfig } from "./statebuilders/views" ;
90
98
import { Ng2ViewDeclaration , NG2_INJECTOR_TOKEN } from "./interface" ;
91
- import { UIRouterConfig } from "./uiRouterConfig" ;
99
+ import { applyRootModuleConfig , applyModuleConfig } from "./uiRouterConfig" ;
92
100
import { Globals } from "../globals" ;
93
101
import { UIRouterLocation } from "./location" ;
94
102
import { services } from "../common/coreservices" ;
95
103
import { 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" ;
99
105
import { UIRouterRx } from "./rx" ;
100
- import { LocationStrategy , HashLocationStrategy , PathLocationStrategy } from "@angular/common" ;
101
106
102
107
/**
103
108
* This is a factory function for a UIRouter instance
104
109
*
105
110
* Creates a UIRouter instance and configures it for Angular 2, then invokes router bootstrap.
106
111
* This function is used as an Angular 2 `useFactory` Provider.
107
112
*/
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
+
109
124
// ----------------- Monkey Patches ----------------
110
125
// Monkey patch the services.$injector to the ng2 Injector
111
126
services . $injector . get = injector . get . bind ( injector ) ;
@@ -127,7 +142,6 @@ let uiRouterFactory = (routerConfig: UIRouterConfig, location: UIRouterLocation,
127
142
128
143
// Apply statebuilder decorator for ng2 NgModule registration
129
144
registry . stateQueue . flush ( router . stateService ) ;
130
- registry . decorator ( 'resolvables' , ngModuleResolvablesBuilder ) ;
131
145
132
146
// Prep the tree of NgModule by placing the root NgModule's Injector on the root state.
133
147
let ng2InjectorResolvable = Resolvable . fromData ( NG2_INJECTOR_TOKEN , injector ) ;
@@ -139,13 +153,8 @@ let uiRouterFactory = (routerConfig: UIRouterConfig, location: UIRouterLocation,
139
153
registry . stateQueue . autoFlush ( router . stateService ) ;
140
154
141
155
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 ) ) ;
149
158
150
159
// Start monitoring the URL
151
160
if ( ! router . urlRouterProvider . interceptDeferred ) {
@@ -158,55 +167,25 @@ let uiRouterFactory = (routerConfig: UIRouterConfig, location: UIRouterLocation,
158
167
} ;
159
168
160
169
export const _UIROUTER_INSTANCE_PROVIDERS : Provider [ ] = [
161
- { provide : UIRouter , useFactory : uiRouterFactory , deps : [ UIRouterConfig , UIRouterLocation , Injector ] } ,
170
+ { provide : UIRouter , useFactory : uiRouterFactory , deps : [ UIRouterLocation , Injector ] } ,
162
171
{ provide : UIRouterLocation , useClass : UIRouterLocation } ,
172
+ { provide : UIView . PARENT_INJECT , useFactory : ( r : StateRegistry ) => { return { fqn : null , context : r . root ( ) } as ParentUIViewInject } , deps : [ StateRegistry ] } ,
163
173
] ;
164
174
165
- export const _UIROUTER_PROVIDERS : Provider [ ] = [
175
+ export const _UIROUTER_SERVICE_PROVIDERS : Provider [ ] = [
166
176
{ provide : StateService , useFactory : ( r : UIRouter ) => r . stateService , deps : [ UIRouter ] } ,
167
177
{ provide : TransitionService , useFactory : ( r : UIRouter ) => r . transitionService , deps : [ UIRouter ] } ,
168
178
{ provide : UrlMatcherFactory , useFactory : ( r : UIRouter ) => r . urlMatcherFactory , deps : [ UIRouter ] } ,
169
179
{ provide : UrlRouter , useFactory : ( r : UIRouter ) => r . urlRouter , deps : [ UIRouter ] } ,
170
180
{ provide : ViewService , useFactory : ( r : UIRouter ) => r . viewService , deps : [ UIRouter ] } ,
171
181
{ provide : StateRegistry , useFactory : ( r : UIRouter ) => r . stateRegistry , deps : [ UIRouter ] } ,
172
182
{ 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 ] }
175
183
] ;
176
184
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
-
206
185
/**
207
186
* The UI-Router providers, for use in your application bootstrap
208
187
*
209
- * @deprecated use [[UIRouterModule]] and [[provideUIRouter ]]
188
+ * @deprecated use [[UIRouterModule.forRoot ]]
210
189
*/
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 ) ;
212
191
0 commit comments