fix(ivy): use the root view injector when resolving dependencies (#27090)

PR Close #27090
This commit is contained in:
Marc Laval
2018-11-14 17:04:22 +01:00
committed by Andrew Kushnir
parent 8a626288a6
commit 1c9e526a83
7 changed files with 221 additions and 26 deletions

View File

@ -72,6 +72,25 @@ export const SCHEDULER = new InjectionToken<((fn: () => void) => void)>('SCHEDUL
export const WRAP_RENDERER_FACTORY2 =
new InjectionToken<(rf: RendererFactory2) => RendererFactory2>('WRAP_RENDERER_FACTORY2');
const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
function createChainedInjector(rootViewInjector: Injector, moduleInjector: Injector): Injector {
return {
get: <T>(token: Type<T>| InjectionToken<T>, notFoundValue?: T): T => {
const value = rootViewInjector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);
if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
// Return the value from the root element injector when
// - it provides it
// (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
return value;
}
return moduleInjector.get(token, notFoundValue);
}
};
}
/**
* Render3 implementation of {@link viewEngine_ComponentFactory}.
*/
@ -122,7 +141,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
// Create the root view. Uses empty TView and ContentTemplate.
const rootView: LViewData = createLViewData(
renderer, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags);
rootView[INJECTOR] = ngModule && ngModule.injector || null;
rootView[INJECTOR] = ngModule ? createChainedInjector(injector, ngModule.injector) : injector;
// rootView is the parent when bootstrapping
const oldView = enterView(rootView, null);

View File

@ -236,9 +236,12 @@ export function getParentInjectorTNode(
}
let viewOffset = getParentInjectorViewOffset(location);
// view offset is 1
let parentView = startView;
let parentTNode = startView[HOST_NODE] as TElementNode;
while (viewOffset > 0) {
// view offset is superior to 1
while (viewOffset > 1) {
parentView = parentView[DECLARATION_VIEW] !;
parentTNode = parentView[HOST_NODE] as TElementNode;
viewOffset--;

View File

@ -8,6 +8,7 @@
import {ChangeDetectorRef as ViewEngine_ChangeDetectorRef} from '../change_detection/change_detector_ref';
import {Injector, NullInjector} from '../di/injector';
import {InjectFlags} from '../di/injector_compatibility';
import {ComponentFactory as viewEngine_ComponentFactory, ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';
import {ElementRef as ViewEngine_ElementRef} from '../linker/element_ref';
import {NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory';
@ -159,7 +160,8 @@ export class NodeInjector implements Injector {
private _hostView: LViewData) {}
get(token: any, notFoundValue?: any): any {
return getOrCreateInjectable(this._tNode, this._hostView, token, notFoundValue);
return getOrCreateInjectable(
this._tNode, this._hostView, token, InjectFlags.Default, notFoundValue);
}
}