Skip to content

Commit

Permalink
chore(overlay): change ComponentResolver to ComponentFactoryResolver (#…
Browse files Browse the repository at this point in the history
…1027)

* wip remove component resolver

* portal and overlay

* dialog

* also remove tcb from overlay-directives-spec
  • Loading branch information
jelbourn authored Aug 14, 2016
1 parent 5160f58 commit 2411c24
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 244 deletions.
29 changes: 13 additions & 16 deletions src/components/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
import {
inject,
fakeAsync,
async,
ComponentFixture,
TestBed,
} from '@angular/core/testing';
import {
Component,
Directive,
ViewChild,
ViewContainerRef,
} from '@angular/core';
import {inject, fakeAsync, async, ComponentFixture, TestBed} from '@angular/core/testing';
import {NgModule, Component, Directive, ViewChild, ViewContainerRef} from '@angular/core';
import {MdDialog, MdDialogModule} from './dialog';
import {OverlayContainer} from '@angular2-material/core/overlay/overlay-container';
import {MdDialogConfig} from './dialog-config';
import {MdDialogRef} from './dialog-ref';



describe('MdDialog', () => {
let dialog: MdDialog;
let overlayContainerElement: HTMLElement;
Expand All @@ -27,8 +15,7 @@ describe('MdDialog', () => {

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MdDialogModule],
declarations: [PizzaMsg, ComponentWithChildViewContainer, DirectiveWithViewContainer],
imports: [MdDialogModule, DialogTestModule],
providers: [
{provide: OverlayContainer, useFactory: () => {
overlayContainerElement = document.createElement('div');
Expand Down Expand Up @@ -144,3 +131,13 @@ class PizzaMsg {
constructor(public dialogRef: MdDialogRef<PizzaMsg>) { }
}

// Create a real (non-test) NgModule as a workaround for
// https://github.com/angular/angular/issues/10760
const TEST_DIRECTIVES = [ComponentWithChildViewContainer, PizzaMsg, DirectiveWithViewContainer];
@NgModule({
imports: [MdDialogModule],
exports: TEST_DIRECTIVES,
declarations: TEST_DIRECTIVES,
entryComponents: [ComponentWithChildViewContainer, PizzaMsg],
})
class DialogTestModule { }
35 changes: 9 additions & 26 deletions src/core/overlay/overlay-directives.spec.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,30 @@
import {
inject,
async,
fakeAsync,
flushMicrotasks,
addProviders,
TestComponentBuilder,
ComponentFixture,
TestBed,
} from '@angular/core/testing';
import {async, fakeAsync, flushMicrotasks, ComponentFixture, TestBed} from '@angular/core/testing';
import {Component, ViewChild} from '@angular/core';
import {ConnectedOverlayDirective, OverlayModule} from './overlay-directives';
import {OverlayContainer} from './overlay-container';
import {ConnectedPositionStrategy} from './position/connected-position-strategy';


describe('Overlay directives', () => {
let builder: TestComponentBuilder;
let overlayContainerElement: HTMLElement;
let fixture: ComponentFixture<ConnectedOverlayDirectiveTest>;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [OverlayModule],
declarations: [ConnectedOverlayDirectiveTest],
providers: [
{provide: OverlayContainer, useFactory: () => {
overlayContainerElement = document.createElement('div');
return {getContainerElement: () => overlayContainerElement};
}}
],
});

addProviders([
{provide: OverlayContainer, useFactory: () => {
overlayContainerElement = document.createElement('div');
return {getContainerElement: () => overlayContainerElement};
}}
]);
}));

beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
builder = tcb;
}));

beforeEach(async(() => {
builder.createAsync(ConnectedOverlayDirectiveTest).then(f => {
fixture = f;
fixture.detectChanges();
});
fixture = TestBed.createComponent(ConnectedOverlayDirectiveTest);
fixture.detectChanges();
}));

it(`should create an overlay and attach the directive's template`, () => {
Expand Down
52 changes: 23 additions & 29 deletions src/core/overlay/overlay.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import {
inject,
fakeAsync,
flushMicrotasks,
TestComponentBuilder,
TestBed,
async,
} from '@angular/core/testing';
import {Component, ViewChild, ViewContainerRef} from '@angular/core';
import {inject, fakeAsync, flushMicrotasks, TestBed, async} from '@angular/core/testing';
import {NgModule, Component, ViewChild, ViewContainerRef} from '@angular/core';
import {TemplatePortalDirective, PortalModule} from '../portal/portal-directives';
import {TemplatePortal, ComponentPortal} from '../portal/portal';
import {Overlay} from './overlay';
Expand All @@ -18,36 +11,32 @@ import {OverlayModule} from './overlay-directives';


describe('Overlay', () => {
let builder: TestComponentBuilder;
let overlay: Overlay;
let componentPortal: ComponentPortal<PizzaMsg>;
let templatePortal: TemplatePortal;
let overlayContainerElement: HTMLElement;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [OverlayModule, PortalModule],
declarations: [TestComponentWithTemplatePortals, PizzaMsg],
imports: [OverlayModule, PortalModule, OverlayTestModule],
providers: [
{provide: OverlayContainer, useFactory: () => {
overlayContainerElement = document.createElement('div');
return {getContainerElement: () => overlayContainerElement};
}}
]
});
}));

TestBed.compileComponents();
}));

let deps = [TestComponentBuilder, Overlay];
beforeEach(fakeAsync(inject(deps, (tcb: TestComponentBuilder, o: Overlay) => {
builder = tcb;
beforeEach(fakeAsync(inject([Overlay], (o: Overlay) => {
overlay = o;

builder.createAsync(TestComponentWithTemplatePortals).then(fixture => {
fixture.detectChanges();
templatePortal = fixture.componentInstance.templatePortal;
componentPortal = new ComponentPortal(PizzaMsg, fixture.componentInstance.viewContainerRef);
});
let fixture = TestBed.createComponent(TestComponentWithTemplatePortals);
fixture.detectChanges();
templatePortal = fixture.componentInstance.templatePortal;
componentPortal = new ComponentPortal(PizzaMsg, fixture.componentInstance.viewContainerRef);

flushMicrotasks();
})));
Expand Down Expand Up @@ -140,24 +129,29 @@ describe('Overlay', () => {


/** Simple component for testing ComponentPortal. */
@Component({
selector: 'pizza-msg',
template: '<p>Pizza</p>',
})
@Component({template: '<p>Pizza</p>'})
class PizzaMsg { }


/** Test-bed component that contains a TempatePortal and an ElementRef. */
@Component({
selector: 'portal-test',
template: `<template portal>Cake</template>`,
})
@Component({template: `<template portal>Cake</template>`})
class TestComponentWithTemplatePortals {
@ViewChild(TemplatePortalDirective) templatePortal: TemplatePortalDirective;

constructor(public viewContainerRef: ViewContainerRef) { }
}

// Create a real (non-test) NgModule as a workaround for
// https://github.com/angular/angular/issues/10760
const TEST_COMPONENTS = [PizzaMsg, TestComponentWithTemplatePortals];
@NgModule({
imports: [OverlayModule, PortalModule],
exports: TEST_COMPONENTS,
declarations: TEST_COMPONENTS,
entryComponents: TEST_COMPONENTS,
})
class OverlayTestModule { }

class FakePositionStrategy implements PositionStrategy {
apply(element: Element): Promise<void> {
element.classList.add('fake-positioned');
Expand Down
6 changes: 3 additions & 3 deletions src/core/overlay/overlay.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
ComponentResolver,
ComponentFactoryResolver,
Injectable,
} from '@angular/core';
import {OverlayState} from './overlay-state';
Expand Down Expand Up @@ -28,7 +28,7 @@ let defaultState = new OverlayState();
@Injectable()
export class Overlay {
constructor(private _overlayContainer: OverlayContainer,
private _componentResolver: ComponentResolver,
private _componentFactoryResolver: ComponentFactoryResolver,
private _positionBuilder: OverlayPositionBuilder) {}

/**
Expand Down Expand Up @@ -68,7 +68,7 @@ export class Overlay {
* @returns A portal host for the given DOM element.
*/
private _createPortalHost(pane: HTMLElement): DomPortalHost {
return new DomPortalHost(pane, this._componentResolver);
return new DomPortalHost(pane, this._componentFactoryResolver);
}

/**
Expand Down
28 changes: 14 additions & 14 deletions src/core/portal/dom-portal-host.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ComponentResolver, ComponentRef, EmbeddedViewRef} from '@angular/core';
import {ComponentFactoryResolver, ComponentRef, EmbeddedViewRef} from '@angular/core';
import {BasePortalHost, ComponentPortal, TemplatePortal} from './portal';
import {MdComponentPortalAttachedToDomWithoutOriginError} from './portal-errors';

Expand All @@ -12,27 +12,27 @@ import {MdComponentPortalAttachedToDomWithoutOriginError} from './portal-errors'
export class DomPortalHost extends BasePortalHost {
constructor(
private _hostDomElement: Element,
private _componentResolver: ComponentResolver) {
private _componentFactoryResolver: ComponentFactoryResolver) {
super();
}

/** Attach the given ComponentPortal to DOM element using the ComponentResolver. */
/** Attach the given ComponentPortal to DOM element using the ComponentFactoryResolver. */
attachComponentPortal<T>(portal: ComponentPortal<T>): Promise<ComponentRef<T>> {
if (portal.viewContainerRef == null) {
throw new MdComponentPortalAttachedToDomWithoutOriginError();
}

return this._componentResolver.resolveComponent(portal.component).then(componentFactory => {
let ref = portal.viewContainerRef.createComponent(
componentFactory,
portal.viewContainerRef.length,
portal.injector || portal.viewContainerRef.parentInjector);

let hostView = <EmbeddedViewRef<any>> ref.hostView;
this._hostDomElement.appendChild(hostView.rootNodes[0]);
this.setDisposeFn(() => ref.destroy());
return ref;
});
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(portal.component);
let ref = portal.viewContainerRef.createComponent(
componentFactory,
portal.viewContainerRef.length,
portal.injector || portal.viewContainerRef.parentInjector);

let hostView = <EmbeddedViewRef<any>> ref.hostView;
this._hostDomElement.appendChild(hostView.rootNodes[0]);
this.setDisposeFn(() => ref.destroy());

return Promise.resolve(ref);
}

attachTemplatePortal(portal: TemplatePortal): Promise<Map<string, any>> {
Expand Down
21 changes: 10 additions & 11 deletions src/core/portal/portal-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import {
ComponentRef,
Directive,
TemplateRef,
ComponentResolver,
ComponentFactoryResolver,
ViewContainerRef
} from '@angular/core';
import {Portal, TemplatePortal, ComponentPortal, BasePortalHost} from './portal';



/**
* Directive version of a `TemplatePortal`. Because the directive *is* a TemplatePortal,
* the directive instance itself can be attached to a host, enabling declarative use of portals.
Expand Down Expand Up @@ -46,7 +45,7 @@ export class PortalHostDirective extends BasePortalHost {
private _portal: Portal<any>;

constructor(
private _componentResolver: ComponentResolver,
private _componentFactoryResolver: ComponentFactoryResolver,
private _viewContainerRef: ViewContainerRef) {
super();
}
Expand All @@ -59,7 +58,7 @@ export class PortalHostDirective extends BasePortalHost {
this._replaceAttachedPortal(p);
}

/** Attach the given ComponentPortal to this PortlHost using the ComponentResolver. */
/** Attach the given ComponentPortal to this PortlHost using the ComponentFactoryResolver. */
attachComponentPortal<T>(portal: ComponentPortal<T>): Promise<ComponentRef<T>> {
portal.setAttachedHost(this);

Expand All @@ -69,14 +68,14 @@ export class PortalHostDirective extends BasePortalHost {
portal.viewContainerRef :
this._viewContainerRef;

return this._componentResolver.resolveComponent(portal.component).then(componentFactory => {
let ref = viewContainerRef.createComponent(
componentFactory, viewContainerRef.length,
portal.injector || viewContainerRef.parentInjector);
let componentFactory =
this._componentFactoryResolver.resolveComponentFactory(portal.component);
let ref = viewContainerRef.createComponent(
componentFactory, viewContainerRef.length,
portal.injector || viewContainerRef.parentInjector);

this.setDisposeFn(() => ref.destroy());
return ref;
});
this.setDisposeFn(() => ref.destroy());
return Promise.resolve(ref);
}

/** Attach the given TemplatePortal to this PortlHost as an embedded View. */
Expand Down
Loading

0 comments on commit 2411c24

Please sign in to comment.