Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: uiView component injector #978

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions src/directives/uiView.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {
Component,
ComponentFactory,
ComponentFactoryResolver,
ComponentMirror,
ComponentRef,
Inject,
Injector,
Input,
OnDestroy,
OnInit,
reflectComponentType,
ViewChild,
ViewContainerRef,
} from '@angular/core';
Expand All @@ -32,7 +32,6 @@ import {
ViewContext,
} from '@uirouter/core';
import { Ng2ViewConfig } from '../statebuilders/views';
import { MergeInjector } from '../mergeInjector';

/** @hidden */
let id = 0;
Expand All @@ -57,7 +56,7 @@ interface InputMapping {
*
* @internal
*/
const ng2ComponentInputs = (factory: ComponentFactory<any>): InputMapping[] => {
const ng2ComponentInputs = (factory: ComponentMirror<any>): InputMapping[] => {
return factory.inputs.map((input) => ({ prop: input.propName, token: input.templateName }));
};

Expand Down Expand Up @@ -290,12 +289,20 @@ export class UIView implements OnInit, OnDestroy {
const componentClass = config.viewDecl.component;

// Create the component
const compFactoryResolver = componentInjector.get(ComponentFactoryResolver);
const compFactory = compFactoryResolver.resolveComponentFactory(componentClass);
this._componentRef = this._componentTarget.createComponent(compFactory, undefined, componentInjector);
const moduleInjector = context.getResolvable(NATIVE_INJECTOR_TOKEN).data;

this._componentRef = this._componentTarget.createComponent(componentClass, {
injector: componentInjector,
environmentInjector: moduleInjector
});

// Wire resolves to @Input()s
this._applyInputBindings(compFactory, this._componentRef.instance, context, componentClass);
this._applyInputBindings(
reflectComponentType(componentClass),
this._componentRef.instance,
context,
componentClass
);
}

/**
Expand All @@ -321,10 +328,8 @@ export class UIView implements OnInit, OnDestroy {
newProviders.push({ provide: UIView.PARENT_INJECT, useValue: parentInject });

const parentComponentInjector = this.viewContainerRef.injector;
const moduleInjector = context.getResolvable(NATIVE_INJECTOR_TOKEN).data;
const mergedParentInjector = new MergeInjector(moduleInjector, parentComponentInjector);

return Injector.create(newProviders, mergedParentInjector);
return Injector.create({ providers: newProviders, parent: parentComponentInjector });
}

/**
Expand All @@ -333,7 +338,7 @@ export class UIView implements OnInit, OnDestroy {
* Finds component inputs which match resolves (by name) and sets the input value
* to the resolve data.
*/
private _applyInputBindings(factory: ComponentFactory<any>, component: any, context: ResolveContext, componentClass) {
private _applyInputBindings(factory: ComponentMirror<any>, component: any, context: ResolveContext, componentClass) {
const bindings = this._uiViewData.config.viewDecl['bindings'] || {};
const explicitBoundProps = Object.keys(bindings);

Expand Down
39 changes: 6 additions & 33 deletions src/lazyLoad/lazyLoadNgModule.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { NgModuleRef, Injector, NgModuleFactory, Type, Compiler } from '@angular/core';
import { NgModuleRef, Injector, Type, createNgModule } from '@angular/core';
import {
Transition,
LazyLoadResult,
UIRouter,
Resolvable,
NATIVE_INJECTOR_TOKEN,
isString,
unnestR,
inArray,
StateObject,
Expand Down Expand Up @@ -72,42 +71,16 @@ export function loadNgModule(
): (transition: Transition, stateObject: StateDeclaration) => Promise<LazyLoadResult> {
return (transition: Transition, stateObject: StateDeclaration) => {
const ng2Injector = transition.injector().get(NATIVE_INJECTOR_TOKEN);

const createModule = (factory: NgModuleFactory<any>) => factory.create(ng2Injector);

const unwrapEsModuleDefault = x => (x && x.__esModule && x['default'] ? x['default'] : x);
const applyModule = (moduleRef: NgModuleRef<any>) => applyNgModule(transition, moduleRef, ng2Injector, stateObject);

return loadModuleFactory(moduleToLoad, ng2Injector).then(createModule).then(applyModule);
return Promise.resolve(moduleToLoad())
.then(unwrapEsModuleDefault)
.then((ngModule: Type<any>) => createNgModule(ngModule, ng2Injector))
.then(applyModule);
};
}

/**
* Returns the module factory that can be used to instantiate a module
*
* For a Type<any> or Promise<Type<any>> this:
* - Compiles the component type (if not running with AOT)
* - Returns the NgModuleFactory resulting from compilation (or direct loading if using AOT) as a Promise
*
* @internal
*/
export function loadModuleFactory(
moduleToLoad: ModuleTypeCallback,
ng2Injector: Injector
): Promise<NgModuleFactory<any>> {
const compiler: Compiler = ng2Injector.get(Compiler);

const unwrapEsModuleDefault = (x) => (x && x.__esModule && x['default'] ? x['default'] : x);

return Promise.resolve(moduleToLoad())
.then(unwrapEsModuleDefault)
.then((t: NgModuleFactory<any> | Type<any>) => {
if (t instanceof NgModuleFactory) {
return t;
}
return compiler.compileModuleAsync(t);
});
}

/**
* Apply the UI-Router Modules found in the lazy loaded module.
*
Expand Down
39 changes: 0 additions & 39 deletions src/mergeInjector.ts

This file was deleted.