fix: element injector vs module injector (#15044)

fixes #12869
fixes #12889
fixes #13885
fixes #13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
This commit is contained in:
Victor Berchet
2017-03-14 16:26:17 -07:00
committed by Chuck Jazdzewski
parent f093501501
commit 13686bb518
29 changed files with 627 additions and 242 deletions

View File

@ -292,8 +292,7 @@ export class TestBed implements Injector {
const imports = [this.ngModule, this._imports];
const schemas = this._schemas;
@NgModule(
{providers: providers, declarations: declarations, imports: imports, schemas: schemas})
@NgModule({providers, declarations, imports, schemas})
class DynamicTestModule {
}
@ -359,10 +358,12 @@ export class TestBed implements Injector {
this._initIfNeeded();
const componentFactory = this._moduleWithComponentFactories.componentFactories.find(
(compFactory) => compFactory.componentType === component);
if (!componentFactory) {
throw new Error(
`Cannot create the component ${stringify(component)} as it was not imported into the testing module!`);
}
const noNgZone = this.get(ComponentFixtureNoNgZone, false);
const autoDetect: boolean = this.get(ComponentFixtureAutoDetect, false);
const ngZone: NgZone = noNgZone ? null : this.get(NgZone, null);
@ -371,7 +372,8 @@ export class TestBed implements Injector {
testComponentRenderer.insertRootElement(rootElId);
const initComponent = () => {
const componentRef = componentFactory.create(this, [], `#${rootElId}`);
const componentRef =
componentFactory.create(Injector.NULL, [], `#${rootElId}`, this._moduleRef);
return new ComponentFixture<T>(componentRef, ngZone, autoDetect);
};