refactor(core): introduce ComponentFactory.

Each compile template now exposes a `<CompName>NgFactory` variable
with an instance of a `ComponentFactory`.
Calling `ComponentFactory.create` returns a `ComponentRef` that can
be used directly.

BREAKING CHANGE:
- `Compiler` is renamed to `ComponentResolver`,
  `Compiler.compileInHost` has been renamed to `ComponentResolver.resolveComponent`.
- `ComponentRef.dispose` is renamed to `ComponentRef.destroy`
- `ViewContainerRef.createHostView` is renamed to `ViewContainerRef.createComponent`
- `ComponentFixture_` has been removed, the class `ComponentFixture`
  can now be created directly as it is no more using private APIs.
This commit is contained in:
Tobias Bosch
2016-04-13 17:05:17 -07:00
parent 41404057cf
commit 0c600cf6e3
66 changed files with 611 additions and 849 deletions

View File

@ -1,51 +0,0 @@
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {provide} from 'angular2/core';
import {Compiler} from 'angular2/src/core/linker/compiler';
import {reflector, ReflectionInfo} from 'angular2/src/core/reflection/reflection';
import {Compiler_} from "angular2/src/core/linker/compiler";
import {HostViewFactory} from 'angular2/src/core/linker/view';
import {HostViewFactoryRef_} from 'angular2/src/core/linker/view_ref';
export function main() {
describe('Compiler', () => {
var someHostViewFactory;
beforeEachProviders(() => [provide(Compiler, {useClass: Compiler_})]);
beforeEach(inject([Compiler], (_compiler) => {
someHostViewFactory = new HostViewFactory(null, null);
reflector.registerType(SomeComponent, new ReflectionInfo([someHostViewFactory]));
}));
it('should read the template from an annotation',
inject([AsyncTestCompleter, Compiler], (async, compiler: Compiler) => {
compiler.compileInHost(SomeComponent)
.then((hostViewFactoryRef: HostViewFactoryRef_) => {
expect(hostViewFactoryRef.internalHostViewFactory).toBe(someHostViewFactory);
async.done();
return null;
});
}));
it('should clear the cache', inject([Compiler], (compiler) => {
// Nothing to assert for now...
compiler.clearCache();
}));
});
}
class SomeComponent {}

View File

@ -24,7 +24,6 @@ import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component
import {ElementRef, ElementRef_} from 'angular2/src/core/linker/element_ref';
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {ComponentFixture_} from "angular2/src/testing/test_component_builder";
import {BaseException} from 'angular2/src/facade/exceptions';
import {PromiseWrapper} from 'angular2/src/facade/promise';
@ -61,14 +60,14 @@ export function main() {
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc')
.then(ref => {
ref.dispose();
ref.destroy();
expect(tc.debugElement.nativeElement).toHaveText("Location;");
async.done();
});
});
}));
it('should allow to dispose even if the location has been removed',
it('should allow to destroy even if the location has been removed',
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
@ -95,7 +94,7 @@ export function main() {
tc.detectChanges();
expect(tc.debugElement.nativeElement).toHaveText("");
ref.dispose();
ref.destroy();
expect(tc.debugElement.nativeElement).toHaveText("");
async.done();
});
@ -236,7 +235,7 @@ export function main() {
expect(firstSibling).toHaveText("DynamicallyLoaded;");
expect(secondSibling).toHaveText("DynamicallyLoaded2;");
ref2.dispose();
ref2.destroy();
firstSibling = DOM.nextSibling(tc.debugElement.nativeElement);
secondSibling = DOM.nextSibling(firstSibling);
@ -302,7 +301,7 @@ export function main() {
DOM.appendChild(doc.body, rootEl);
loader.loadAsRoot(ChildComp, null, injector)
.then((componentRef) => {
var el = new ComponentFixture_(componentRef);
var el = new ComponentFixture(componentRef);
expect(rootEl.parentNode).toBe(doc.body);
@ -316,7 +315,7 @@ export function main() {
expect(rootEl).toHaveText('new');
componentRef.dispose();
componentRef.destroy();
expect(rootEl.parentNode).toBeFalsy();

View File

@ -87,7 +87,7 @@ import {QueryList} from 'angular2/src/core/linker/query_list';
import {ViewContainerRef} from 'angular2/src/core/linker/view_container_ref';
import {EmbeddedViewRef} from 'angular2/src/core/linker/view_ref';
import {Compiler} from 'angular2/src/core/linker/compiler';
import {ComponentResolver} from 'angular2/src/core/linker/component_resolver';
import {ElementRef} from 'angular2/src/core/linker/element_ref';
import {TemplateRef} from 'angular2/src/core/linker/template_ref';
@ -1167,7 +1167,7 @@ function declareTests(isJit: boolean) {
describe('dynamic ViewContainers', () => {
it('should allow to create a ViewContainerRef at any bound location',
inject([TestComponentBuilder, AsyncTestCompleter, Compiler],
inject([TestComponentBuilder, AsyncTestCompleter, ComponentResolver],
(tcb: TestComponentBuilder, async, compiler) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><dynamic-vp #dynamic></dynamic-vp></div>',
@ -1946,13 +1946,13 @@ class SimpleImperativeViewComponent {
@Injectable()
class DynamicViewport {
done: Promise<any>;
constructor(vc: ViewContainerRef, compiler: Compiler) {
constructor(vc: ViewContainerRef, compiler: ComponentResolver) {
var myService = new MyService();
myService.greeting = 'dynamic greet';
var bindings = Injector.resolve([provide(MyService, {useValue: myService})]);
this.done = compiler.compileInHost(ChildCompUsingService)
.then((hostPv) => {vc.createHostView(hostPv, 0, bindings)});
this.done = compiler.resolveComponent(ChildCompUsingService)
.then((compFactory) => {vc.createComponent(compFactory, 0, bindings)});
}
}

View File

@ -0,0 +1,47 @@
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {provide} from 'angular2/core';
import {
ComponentResolver,
ReflectorComponentResolver
} from 'angular2/src/core/linker/component_resolver';
import {reflector, ReflectionInfo} from 'angular2/src/core/reflection/reflection';
import {ComponentFactory} from 'angular2/src/core/linker/component_factory';
export function main() {
describe('Compiler', () => {
var someCompFactory;
beforeEachProviders(() => [provide(ComponentResolver, {useClass: ReflectorComponentResolver})]);
beforeEach(inject([ComponentResolver], (_compiler) => {
someCompFactory = new ComponentFactory(null, null, null);
reflector.registerType(SomeComponent, new ReflectionInfo([someCompFactory]));
}));
it('should read the template from an annotation',
inject([AsyncTestCompleter, ComponentResolver], (async, compiler: ComponentResolver) => {
compiler.resolveComponent(SomeComponent)
.then((compFactory: ComponentFactory) => {
expect(compFactory).toBe(someCompFactory);
async.done();
return null;
});
}));
});
}
class SomeComponent {}