Skip to content

Commit

Permalink
fix(NgModule): De-dupe states loaded from NgModule
Browse files Browse the repository at this point in the history
Works around Angular bug: angular/angular#13652

Closes #42
  • Loading branch information
christopherthielen committed Mar 5, 2017
1 parent a285218 commit ffe85cb
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 14 deletions.
24 changes: 13 additions & 11 deletions src/lazyLoad/lazyLoadNgModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
/** */
import { NgModuleRef, Injector, NgModuleFactory, Type, Compiler, NgModuleFactoryLoader } from "@angular/core";
import {
Transition, LazyLoadResult, UIRouter, Resolvable, NATIVE_INJECTOR_TOKEN, isString, unnestR, inArray
Transition, LazyLoadResult, UIRouter, Resolvable, NATIVE_INJECTOR_TOKEN, isString, unnestR, inArray, StateObject,
uniqR
} from "ui-router-core";
import { RootModule, UIROUTER_ROOT_MODULE, UIROUTER_MODULE_TOKEN } from "../uiRouterNgModule";
import { RootModule, UIROUTER_ROOT_MODULE, UIROUTER_MODULE_TOKEN, StatesModule } from "../uiRouterNgModule";
import { applyModuleConfig } from "../uiRouterConfig";

/**
Expand Down Expand Up @@ -143,14 +144,20 @@ export function applyNgModule(transition: Transition, ng2Module: NgModuleRef<any
// Final name (without the .**)
let replacementName = isFuture && isFuture[1];

let newRootModules: RootModule[] = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_ROOT_MODULE);
let newRootModules = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_ROOT_MODULE)
.reduce(uniqR, []) as RootModule[];
let newChildModules= multiProviderParentChildDelta(parentInjector, injector, UIROUTER_MODULE_TOKEN)
.reduce(uniqR, []) as StatesModule[];

if (newRootModules.length) {
console.log(newRootModules);
throw new Error('Lazy loaded modules should not contain a UIRouterModule.forRoot() module');
}

let newChildModules: RootModule[] = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_MODULE_TOKEN);
newChildModules.forEach(module => applyModuleConfig(uiRouter, injector, module));
let newStateObjects: StateObject[] = newChildModules
.map(module => applyModuleConfig(uiRouter, injector, module))
.reduce(unnestR, [])
.reduce(uniqR, []);

let replacementState = registry.get(replacementName);
if (!replacementState || replacementState === originalState) {
Expand All @@ -164,16 +171,11 @@ export function applyNgModule(transition: Transition, ng2Module: NgModuleRef<any
// Supply the newly loaded states with the Injector from the lazy loaded NgModule.
// If a tree of states is lazy loaded, only add the injector to the root of the lazy loaded tree.
// The children will get the injector by resolve inheritance.
let newStates = newChildModules.map(module => module.states)
.reduce(unnestR, [])
.map(state => state.$$state());

let newParentStates = newStates.filter(state => !inArray(newStates, state.parent));
let newParentStates = newStateObjects.filter(state => !inArray(newStateObjects, state.parent));

// Add the Injector to the top of the lazy loaded state tree as a resolve
newParentStates.forEach(state => state.resolvables.push(Resolvable.fromData(NATIVE_INJECTOR_TOKEN, injector)));


return {};
}

Expand Down
6 changes: 3 additions & 3 deletions src/uiRouterConfig.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
/** @module ng2 */ /** */
import { UIRouter, isFunction } from "ui-router-core";
import { UIRouter, isFunction, StateObject } from "ui-router-core";
import {StatesModule, RootModule} from "./uiRouterNgModule";
import {Injector} from "@angular/core";
import {isDefined} from "ui-router-core";

export function applyModuleConfig(uiRouter: UIRouter, injector: Injector, options: StatesModule = {}) {
export function applyModuleConfig(uiRouter: UIRouter, injector: Injector, options: StatesModule = {}): StateObject[] {
if (isFunction(options.config)) {
options.config(uiRouter, injector);
}

let states = options.states || [];
states.forEach(state => uiRouter.stateRegistry.register(state));
return states.map(state => uiRouter.stateRegistry.register(state));
}

export function applyRootModuleConfig(uiRouter: UIRouter, injector: Injector, config: RootModule) {
Expand Down

0 comments on commit ffe85cb

Please sign in to comment.