Skip to content

Commit

Permalink
feat(ng2.NgModule): Add module's states to DI using UIROUTER_STATES_T…
Browse files Browse the repository at this point in the history
…OKEN
  • Loading branch information
christopherthielen committed Aug 31, 2016
1 parent f06f6b6 commit 0cb628e
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions src/ng2/routerModule.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {Ng2StateDeclaration} from "./interface";
import {NgModule, NgModuleMetadataType} from "@angular/core";
import {NgModule, NgModuleMetadataType, OpaqueToken} from "@angular/core";
import {UIROUTER_DIRECTIVES} from "./directives/directives";
import {UIROUTER_PROVIDERS} from "./providers";
import {UIView} from "./directives/uiView";
import {uniqR} from "../common/common";

@NgModule({
declarations: [UIROUTER_DIRECTIVES],
Expand All @@ -19,25 +20,28 @@ export class _UIRouterModule {}
* by adding a `states` array.
*/
export interface UIRouterModuleMetadata extends NgModuleMetadataType {
states: Ng2StateDeclaration[]
states?: Ng2StateDeclaration[]
}

export const UIROUTER_STATES_TOKEN = new OpaqueToken("UIRouterStates");

/**
* Declares a NgModule with UI-Router states
*
* A Typescript decorator for declaring a [NgModule](https://angular.io/docs/ts/latest/guide/ngmodule.html)
* which contains UI-Router states.
*
* This decorator analyzes the `states` in the module, and adds module `declarations` and `entryComponents`
* for all routed Components.
*
* This decorator analyzes the `states` in the module.
* It adds all routed `component:`(s) for each state to the module's `declarations` and `entryComponents`.
*
* @example
* ```js
*
* var homeState = { name: 'home', url: '/home', component: Home };
* var aboutState = { name: 'about', url: '/about', component: About };
* @UIRouterModule({
* imports: [BrowserModule],
* declarations: [NonRoutedComponent],
* states: [homeState, aboutState]
* }) export class AppModule {};
* ```
Expand All @@ -47,16 +51,19 @@ export interface UIRouterModuleMetadata extends NgModuleMetadataType {
*/
export function UIRouterModule(moduleMetaData: UIRouterModuleMetadata) {
let states = moduleMetaData.states || [];

// Get the component classes for all views for all states in the module
let components = states.map(state => state.views || { $default: state })
.map(viewObj => Object.keys(viewObj).map(key => viewObj[key].component))
.reduce((acc, arr) => acc.concat(arr), [])
.filter(x => typeof x === 'function');

moduleMetaData.imports = (moduleMetaData.imports || []).concat(_UIRouterModule);
moduleMetaData.declarations = (moduleMetaData.declarations || []).concat(components);
moduleMetaData.entryComponents = (moduleMetaData.entryComponents || []).concat(components);
moduleMetaData.imports = <any[]> (moduleMetaData.imports || []).concat(_UIRouterModule).reduce(uniqR, []);
moduleMetaData.declarations = <any[]> (moduleMetaData.declarations || []).concat(components).reduce(uniqR, []);
moduleMetaData.entryComponents = <any[]> (moduleMetaData.entryComponents || []).concat(components).reduce(uniqR, []);
moduleMetaData.providers = (moduleMetaData.providers || []).concat({ provide: UIROUTER_STATES_TOKEN, useValue: states });

return function(moduleClass) {
return NgModule(moduleMetaData)(moduleClass);
}
}
}

0 comments on commit 0cb628e

Please sign in to comment.