feat(core): allow to add precompiled tokens via a provider

Introduces the new `ANALYZE_FOR_PRECOMPILE` token. This token can be used to
create a virtual provider that will populate the `precompile` fields of
components and app modules based on its
`useValue`. All components that are referenced in the `useValue`
value (either directly or in a nested array or map) will be added
to the `precompile` property.

closes #9874
related to #9726
This commit is contained in:
Tobias Bosch
2016-07-07 10:05:55 -07:00
parent 9d265b6f61
commit 7073cf74fe
12 changed files with 215 additions and 30 deletions

View File

@ -1,6 +1,6 @@
import {LowerCasePipe, NgIf} from '@angular/common';
import {CompilerConfig} from '@angular/compiler';
import {AppModule, AppModuleMetadata, Compiler, Component, ComponentFactoryResolver, ComponentRef, ComponentResolver, DebugElement, Host, Inject, Injectable, Injector, OpaqueToken, Optional, Provider, ReflectiveInjector, SelfMetadata, SkipSelf, SkipSelfMetadata, forwardRef, getDebugNode, provide} from '@angular/core';
import {ANALYZE_FOR_PRECOMPILE, AppModule, AppModuleMetadata, Compiler, Component, ComponentFactoryResolver, ComponentRef, ComponentResolver, DebugElement, Host, Inject, Injectable, Injector, OpaqueToken, Optional, Provider, ReflectiveInjector, SelfMetadata, SkipSelf, SkipSelfMetadata, forwardRef, getDebugNode, provide} from '@angular/core';
import {ComponentFixture, configureCompiler} from '@angular/core/testing';
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
@ -87,6 +87,14 @@ class SomeComp {
class ModuleWithPrecompile {
}
@AppModule({
providers:
[{provide: ANALYZE_FOR_PRECOMPILE, multi: true, useValue: [{a: 'b', component: SomeComp}]}]
})
class ModuleWithAnalyzePrecompileProvider {
}
@Component({
selector: 'comp',
template: `<div [title]="'HELLO' | lowercase"></div><div *ngIf="true"></div>`
@ -137,6 +145,16 @@ function declareTests({useJit}: {useJit: boolean}) {
.toBe(SomeComp);
});
it('should resolve ComponentFactories via ANALYZE_FOR_PRECOMPILE', () => {
let appModule = compiler.compileAppModuleSync(ModuleWithAnalyzePrecompileProvider).create();
expect(appModule.componentFactoryResolver.resolveComponentFactory(SomeComp).componentType)
.toBe(SomeComp);
expect(appModule.injector.get(ComponentFactoryResolver)
.resolveComponentFactory(SomeComp)
.componentType)
.toBe(SomeComp);
});
it('should resolve ComponentFactories for nested modules', () => {
let appModule =
compiler

View File

@ -10,7 +10,7 @@ import {beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeE
import {TestComponentBuilder} from '@angular/compiler/testing';
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {Component, ViewChild, ViewContainerRef, ComponentFactoryResolver, NoComponentFactoryError, ComponentRef, forwardRef} from '@angular/core';
import {Component, ViewChild, ViewContainerRef, ComponentFactoryResolver, NoComponentFactoryError, ComponentRef, forwardRef, ANALYZE_FOR_PRECOMPILE} from '@angular/core';
import {CompilerConfig} from '@angular/compiler';
export function main() {
@ -34,6 +34,17 @@ function declareTests({useJit}: {useJit: boolean}) {
});
}));
it('should resolve ComponentFactories via ANALYZE_FOR_PRECOMPILE',
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
let compFixture = tcb.createSync(CompWithAnalyzePrecompileProvider);
let mainComp: CompWithAnalyzePrecompileProvider = compFixture.componentInstance;
let cfr: ComponentFactoryResolver =
compFixture.debugElement.injector.get(ComponentFactoryResolver);
expect(cfr.resolveComponentFactory(ChildComp).componentType).toBe(ChildComp);
expect(cfr.resolveComponentFactory(NestedChildComp).componentType).toBe(NestedChildComp);
}));
it('should be able to get a component form a parent component (view hiearchy)',
inject(
[TestComponentBuilder, AsyncTestCompleter],
@ -70,6 +81,7 @@ function declareTests({useJit}: {useJit: boolean}) {
async.done();
});
}));
});
}
@ -98,3 +110,18 @@ class ChildComp {
class MainComp {
constructor(public cfr: ComponentFactoryResolver) {}
}
@Component({
selector: 'comp-with-analyze',
template: '',
providers: [{
provide: ANALYZE_FOR_PRECOMPILE,
multi: true,
useValue: [
{a: 'b', component: ChildComp},
{b: 'c', anotherComponent: NestedChildComp},
]
}]
})
class CompWithAnalyzePrecompileProvider {
}