Skip to content

Commit bc17066

Browse files
feat(ng2): Improve ng2 bootstrap flexibility with provideUIRouter() provider factory function
fix(ng2): Update deps to rc.6 Closes #2958
1 parent c9b6570 commit bc17066

File tree

7 files changed

+84
-33
lines changed

7 files changed

+84
-33
lines changed

package.json

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ui-router",
33
"description": "State-based routing for Javascript",
4-
"version": "1.0.0-beta.1",
4+
"version": "1.0.0-beta.2",
55
"scripts": {
66
"test": "npm run test:integrate",
77
"watch": "node_modules/watch/cli.js 'npm run test' src test",
@@ -56,11 +56,11 @@
5656
},
5757
"license": "MIT",
5858
"devDependencies": {
59-
"@angular/common": "=2.0.0-rc.5",
60-
"@angular/compiler": "=2.0.0-rc.5",
61-
"@angular/core": "=2.0.0-rc.5",
62-
"@angular/platform-browser": "=2.0.0-rc.5",
63-
"@angular/platform-browser-dynamic": "=2.0.0-rc.5",
59+
"@angular/common": "=2.0.0-rc.6",
60+
"@angular/compiler": "=2.0.0-rc.6",
61+
"@angular/core": "=2.0.0-rc.6",
62+
"@angular/platform-browser": "=2.0.0-rc.6",
63+
"@angular/platform-browser-dynamic": "=2.0.0-rc.6",
6464
"babel-core": "^5.8.14",
6565
"clone": "^1.0.2",
6666
"conventional-changelog": "^1.1.0",
@@ -82,7 +82,7 @@
8282
"phantomjs-polyfill": "0.0.1",
8383
"reflect-metadata": "=0.1.2",
8484
"remap-istanbul": "^0.6.3",
85-
"rxjs": "=5.0.0-beta.6",
85+
"rxjs": "^5.0.0-beta.11",
8686
"shelljs": "^0.7.0",
8787
"systemjs": "^0.18.4",
8888
"ts-loader": "^0.8.1",
@@ -94,6 +94,6 @@
9494
"webpack": "1.x",
9595
"webpack-dev-server": "1.x",
9696
"yargs": "^4.2.0",
97-
"zone.js": "=0.6.12"
97+
"zone.js": "^0.6.17"
9898
}
9999
}

packages/ng2/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "ui-router-ng2",
33
"description": "State-based routing for Angular 2",
44
"peerDependencies": {
5-
"@angular/core": "^2.0.0-rc.5"
5+
"@angular/core": "^2.0.0-rc.6"
66
},
77
"main": "ng2.js",
88
"typings": "ng2.d.ts"

src/ng2/directives/uiView.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ interface InputMapping {
3030
declare var Reflect: any;
3131

3232
/** @hidden */
33-
const ng2ComponentInputs = (ng2CompClass: Type) => {
33+
const ng2ComponentInputs = (ng2CompClass: Type<any>) => {
3434
/** Get "@Input('foo') _foo" inputs */
3535
let props = Reflect['getMetadata']('propMetadata', ng2CompClass);
3636
let _props = Object.keys(props || {})

src/ng2/interface.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ export interface Ng2ViewDeclaration extends _ViewDeclaration {
223223
* }
224224
* ```
225225
*/
226-
component?: Type;
226+
component?: Type<any>;
227227

228228
/**
229229
* An object which maps `resolve` keys to [[component]] `bindings`.

src/ng2/location.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @module ng2 */ /** */
2-
import {HashLocationStrategy, PlatformLocation, LocationStrategy, UrlChangeListener} from "@angular/common";
2+
import {HashLocationStrategy, PlatformLocation, LocationStrategy, LocationChangeListener} from "@angular/common";
33
import {Injectable} from "@angular/core";
44

55
import {services} from "../common/coreservices";
@@ -60,7 +60,7 @@ export class UIRouterLocation {
6060
console.log(new Error('$location.replace() not impl'))
6161
};
6262

63-
loc.onChange = (cb: UrlChangeListener) => locSt.onPopState(cb);
63+
loc.onChange = (cb: LocationChangeListener) => locSt.onPopState(cb);
6464

6565
let locCfg = <any> services.locationConfig;
6666

src/ng2/providers.ts

+45-8
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
*
4747
* @preferred @module ng2
4848
*/ /** */
49-
import {Injector, OpaqueToken} from "@angular/core";
49+
import {Injector, OpaqueToken, Provider} from "@angular/core";
50+
import {ClassProvider, ExistingProvider, FactoryProvider, TypeProvider, ValueProvider} from "@angular/core"; // has or is using
5051
import {UIRouter} from "../router";
5152
import {PathNode} from "../path/node";
5253
import {StateRegistry} from "../state/stateRegistry";
@@ -62,17 +63,20 @@ import {UIRouterConfig} from "./uiRouterConfig";
6263
import {Globals} from "../globals";
6364
import {UIRouterLocation} from "./location";
6465
import {services} from "../common/coreservices";
65-
import {ProviderLike} from "../state/interface";
6666
import {Resolvable} from "../resolve/resolvable";
6767
import {ngModuleResolvablesBuilder} from "./statebuilders/lazyLoadNgModuleResolvable";
6868
import {flattenR} from "../common/common";
6969
import {UIROUTER_STATES_TOKEN} from "./uiRouterNgModule";
7070
import {UIRouterRx} from "./rx";
71+
import {LocationStrategy, HashLocationStrategy, PathLocationStrategy} from "@angular/common";
7172

7273
export const NG1_UIROUTER_TOKEN = new OpaqueToken("$uiRouter");
7374

7475
/**
75-
* This is a provider factory for a UIRouter instance which is configured for Angular 2
76+
* This is a factory function for a UIRouter instance
77+
*
78+
* Creates a UIRouter instance and configures it for Angular 2, then invokes router bootstrap.
79+
* This function is used as an Angular 2 `useFactory` Provider.
7680
*/
7781
let uiRouterFactory = (injector: Injector) => {
7882
// ----------------- ng1-to-ng2 short circuit ------
@@ -140,10 +144,12 @@ let uiRouterFactory = (injector: Injector) => {
140144
return router;
141145
};
142146

143-
export const _UIROUTER_PROVIDERS: ProviderLike[] = [
144-
{ provide: UIRouterLocation, useClass: UIRouterLocation },
147+
export const _UIROUTER_INSTANCE_PROVIDERS: Provider[] = [
145148
{ provide: UIRouter, useFactory: uiRouterFactory, deps: [Injector] },
149+
{ provide: UIRouterLocation, useClass: UIRouterLocation },
150+
];
146151

152+
export const _UIROUTER_PROVIDERS: Provider[] = [
147153
{ provide: StateService, useFactory: (r: UIRouter) => r.stateService , deps: [UIRouter]},
148154
{ provide: TransitionService, useFactory: (r: UIRouter) => r.transitionService, deps: [UIRouter]},
149155
{ provide: UrlMatcherFactory, useFactory: (r: UIRouter) => r.urlMatcherFactory, deps: [UIRouter]},
@@ -153,10 +159,41 @@ export const _UIROUTER_PROVIDERS: ProviderLike[] = [
153159
{ provide: Globals, useFactory: (r: UIRouter) => r.globals , deps: [UIRouter]},
154160

155161
{ provide: UIView.PARENT_INJECT, useFactory: (r: StateRegistry) => { return { fqn: null, context: r.root() } as ParentUIViewInject }, deps: [StateRegistry]}
156-
]
162+
];
163+
164+
/**
165+
* Provides an Instance of UI-Router for NG2.
166+
*
167+
* Use this on the root NgModule to configure and create an instance of the Angular 2 UIRouter.
168+
*
169+
* @example
170+
* ```js
171+
*
172+
* @UIRouterModule({
173+
* states: [ homeState, aboutState ],
174+
* providers: [ provideUIRouter({ configClass: MyUIRouterConfig, useHash: true }) ],
175+
* bootstrap: [ UIView ]
176+
* }) class RootNgModule {}
177+
*
178+
* platformBrowserDynamic().bootstrapModule(RootNgModule);
179+
* ```
180+
*
181+
* Note: UIRouter should only be provided *once*, on the root module, when bootstrapping the application.
182+
*/
183+
export function provideUIRouter(rootConfig: { configClass?: typeof UIRouterConfig, useHash?: boolean } = {}) {
184+
// Provide the UIRouter instance providers
185+
return _UIROUTER_INSTANCE_PROVIDERS.concat(
186+
// Provide the user-supplied UIRouterConfig class, or use base UIRouterConfig (as a no-op config)
187+
{ provide: UIRouterConfig, useClass: (rootConfig.configClass as any || UIRouterConfig) },
188+
// Provide the PathLocationStrategy by default unless `useHash` is `true`
189+
{ provide: LocationStrategy, useClass: (rootConfig.useHash ? HashLocationStrategy : PathLocationStrategy ) }
190+
);
191+
}
192+
157193
/**
158194
* The UI-Router providers, for use in your application bootstrap
159195
*
160-
* @deprecated use [[UIRouterModule]]
196+
* @deprecated use [[UIRouterModule]] and [[provideUIRouter]]
161197
*/
162-
export const UIROUTER_PROVIDERS = _UIROUTER_PROVIDERS;
198+
export const UIROUTER_PROVIDERS: Provider[] = _UIROUTER_INSTANCE_PROVIDERS.concat(_UIROUTER_PROVIDERS);
199+

src/ng2/uiRouterNgModule.ts

+26-12
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {uniqR, flattenR} from "../common/common";
1111
entryComponents: [UIView],
1212
providers: [_UIROUTER_PROVIDERS]
1313
})
14-
export class UIRouterRootModule {}
14+
export class UIRouterLibraryModule {}
1515

1616
/**
1717
* A module declaration lteral, including UI-Router states.
@@ -28,11 +28,23 @@ export const UIROUTER_STATES_TOKEN = new OpaqueToken("UIRouter States");
2828
/**
2929
* Declares a NgModule with UI-Router states
3030
*
31-
* A Typescript decorator for declaring a [NgModule](https://angular.io/docs/ts/latest/guide/ngmodule.html)
32-
* which contains UI-Router states.
31+
* A Typescript decorator for declaring an [NgModule](https://angular.io/docs/ts/latest/guide/ngmodule.html)
32+
* which contains UI-Router states and/or uses UI-Router directives and providers.
33+
*
34+
* The decorator adds the `UIRouterLibraryModule` NgModule as an import.
35+
* The `UIRouterLibraryModule has the UI-Router directives and providers.
3336
*
34-
* This decorator analyzes the `states` in the module.
35-
* It adds all routed `component:`(s) for each state to the module's `declarations` and `entryComponents`.
37+
* The decorator also analyzes the `states:` property.
38+
* When it finds a state with a routed `component:`, it adds the component
39+
* to the module's `declarations` and `entryComponents`.
40+
*
41+
* Note: adding the component to `entryComponents` instructs the Module Compiler that those
42+
* components should be compiled.
43+
* Otherwise, they would not be automatically discovered as "reachable" by the compiler.
44+
*
45+
* Further, the states found in the `states:` property are added to Dependency Injection
46+
* using a specific token.
47+
* This will automatically register them with the [[StateRegistry]] when the application bootstraps.
3648
*
3749
* @example
3850
* ```js
@@ -41,21 +53,23 @@ export const UIROUTER_STATES_TOKEN = new OpaqueToken("UIRouter States");
4153
* var aboutState = { name: 'about', url: '/about', component: About };
4254
*
4355
* @UIRouterModule({
44-
* imports: [BrowserModule],
45-
* declarations: [NonRoutedComponent],
46-
* states: [homeState, aboutState]
56+
* imports: [ BrowserModule ],
57+
* declarations: [ NonRoutedComponent ],
58+
* states: [ homeState, aboutState ]
4759
* }) export class AppModule {};
4860
* ```
4961
*
50-
* The `UIRouterModule` decorator creates an Angular 2 `NgModule`.
51-
* The equivalent `AppModule` could also be crafted by hand using the `NgModule` decorator:
62+
* ---
63+
*
64+
* Note: the `UIRouterModule` decorator creates a standard Angular 2 `NgModule`.
65+
* The equivalent `AppModule` could also be crafted by hand using only the `NgModule` decorator:
5266
*
5367
* ```
5468
* var homeState = { name: 'home', url: '/home', component: Home };
5569
* var aboutState = { name: 'about', url: '/about', component: About };
5670
*
5771
* @NgModule({
58-
* imports: [BrowserModule, UIRouterRootModule],
72+
* imports: [BrowserModule, UIRouterLibraryModule],
5973
* declarations: [NonRoutedComponent, Home, About],
6074
* entryComponents: [Home, About],
6175
* providers: [
@@ -79,7 +93,7 @@ export function UIRouterModule(moduleMetaData: UIRouterModuleMetadata) {
7993
.reduce((acc, arr) => acc.concat(arr), [])
8094
.filter(x => typeof x === 'function' && x !== UIView);
8195

82-
moduleMetaData.imports = <any[]> (moduleMetaData.imports || []).concat(UIRouterRootModule).reduce(uniqR, []);
96+
moduleMetaData.imports = <any[]> (moduleMetaData.imports || []).concat(UIRouterLibraryModule).reduce(uniqR, []);
8397
moduleMetaData.declarations = <any[]> (moduleMetaData.declarations || []).concat(routedComponents).reduce(uniqR, []);
8498
moduleMetaData.entryComponents = <any[]> (moduleMetaData.entryComponents || []).concat(routedComponents).reduce(uniqR, []);
8599
moduleMetaData.providers = (moduleMetaData.providers || []).concat(statesProvider);

0 commit comments

Comments
 (0)