fix(ivy): link correct ngModule's injector to the bootstrapped component (#28183)
Previously, bootstrapping a component with render3 would create a chained injector with the test bed ngModule instead of the ngModule that the component belongs to. Now when a component belongs to an ngModule, we use that for the chained injector, ensuring the correct injection of any providers that this ngModule contains. FW-776 #resolve PR Close #28183
This commit is contained in:

committed by
Jason Aden

parent
317cc922ac
commit
cbd626413c
@ -22,6 +22,7 @@ import {InternalNgModuleRef, NgModuleFactory, NgModuleRef} from './linker/ng_mod
|
||||
import {InternalViewRef, ViewRef} from './linker/view_ref';
|
||||
import {WtfScopeFn, wtfCreateScope, wtfLeave} from './profile/profile';
|
||||
import {assertNgModuleType} from './render3/assert';
|
||||
import {ComponentFactory as R3ComponentFactory} from './render3/component_ref';
|
||||
import {NgModuleFactory as R3NgModuleFactory} from './render3/ng_module_ref';
|
||||
import {Testability, TestabilityRegistry} from './testability/testability';
|
||||
import {isDevMode} from './util/is_dev_mode';
|
||||
@ -51,6 +52,16 @@ export function compileNgModuleFactory__POST_R3__<M>(
|
||||
return Promise.resolve(new R3NgModuleFactory(moduleType));
|
||||
}
|
||||
|
||||
let isBoundToModule: <C>(cf: ComponentFactory<C>) => boolean = isBoundToModule__PRE_R3__;
|
||||
|
||||
export function isBoundToModule__PRE_R3__<C>(cf: ComponentFactory<C>): boolean {
|
||||
return cf instanceof ComponentFactoryBoundToModule;
|
||||
}
|
||||
|
||||
export function isBoundToModule__POST_R3__<C>(cf: ComponentFactory<C>): boolean {
|
||||
return (cf as R3ComponentFactory<C>).isBoundToModule;
|
||||
}
|
||||
|
||||
export const ALLOW_MULTIPLE_PLATFORMS = new InjectionToken<boolean>('AllowMultipleToken');
|
||||
|
||||
|
||||
@ -467,9 +478,7 @@ export class ApplicationRef {
|
||||
this.componentTypes.push(componentFactory.componentType);
|
||||
|
||||
// Create a factory associated with the current module if it's not bound to some other
|
||||
const ngModule = componentFactory instanceof ComponentFactoryBoundToModule ?
|
||||
null :
|
||||
this._injector.get(NgModuleRef);
|
||||
const ngModule = isBoundToModule(componentFactory) ? null : this._injector.get(NgModuleRef);
|
||||
const selectorOrNode = rootSelectorOrNode || componentFactory.selector;
|
||||
const compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
|
||||
|
||||
|
@ -211,7 +211,8 @@ export {
|
||||
//
|
||||
// no code actually imports these symbols from the @angular/core entry point
|
||||
export {
|
||||
compileNgModuleFactory__POST_R3__ as ɵcompileNgModuleFactory__POST_R3__
|
||||
compileNgModuleFactory__POST_R3__ as ɵcompileNgModuleFactory__POST_R3__,
|
||||
isBoundToModule__POST_R3__ as ɵisBoundToModule__POST_R3__
|
||||
} from './application_ref';
|
||||
export {
|
||||
SWITCH_COMPILE_COMPONENT__POST_R3__ as ɵSWITCH_COMPILE_COMPONENT__POST_R3__,
|
||||
|
@ -102,6 +102,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
||||
selector: string;
|
||||
componentType: Type<any>;
|
||||
ngContentSelectors: string[];
|
||||
isBoundToModule: boolean;
|
||||
|
||||
get inputs(): {propName: string; templateName: string;}[] {
|
||||
return toRefArray(this.componentDef.inputs);
|
||||
@ -124,6 +125,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
||||
// It is implicitly expected as the first item in the projectable nodes array.
|
||||
this.ngContentSelectors =
|
||||
componentDef.ngContentSelectors ? ['*', ...componentDef.ngContentSelectors] : [];
|
||||
this.isBoundToModule = !!ngModule;
|
||||
}
|
||||
|
||||
create(
|
||||
|
Reference in New Issue
Block a user