From 3604adf841d48b42fb05eed6b69a8230ee13d51a Mon Sep 17 00:00:00 2001 From: Dan Bucholtz Date: Wed, 3 Jan 2018 16:23:16 -0600 Subject: [PATCH] refactor(angular): optionally wrap the user's template in --- packages/angular/src/components/ion-nav.ts | 7 +++-- .../providers/angular-component-mounter.ts | 30 +++++++++++++------ .../angular/src/providers/modal-controller.ts | 6 ++-- .../src/providers/popover-controller.ts | 6 ++-- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/packages/angular/src/components/ion-nav.ts b/packages/angular/src/components/ion-nav.ts index 8f3f80e69b..0edd0b130b 100644 --- a/packages/angular/src/components/ion-nav.ts +++ b/packages/angular/src/components/ion-nav.ts @@ -22,11 +22,12 @@ export class IonNavDelegate implements FrameworkDelegate { attachViewToDom(elementOrContainerToMountTo: HTMLIonNavElement, elementOrComponentToMount: Type, _propsOrDataObj?: any, classesToAdd?: string[]): Promise { - return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd); + // wrap whatever the user provides in an ion-page + return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd, true); } - removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { - return this.angularComponentMounter.removeViewFromDom(childElement); + removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) { + return this.angularComponentMounter.removeViewFromDom(parentElement, childElement); } } diff --git a/packages/angular/src/providers/angular-component-mounter.ts b/packages/angular/src/providers/angular-component-mounter.ts index 4f0faaaff3..1a661d91bb 100644 --- a/packages/angular/src/providers/angular-component-mounter.ts +++ b/packages/angular/src/providers/angular-component-mounter.ts @@ -20,45 +20,57 @@ export class AngularComponentMounter { constructor(private defaultCfr: ComponentFactoryResolver, private zone: NgZone, private appRef: ApplicationRef) { } - attachViewToDom(parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type, componentResolveFactory: ComponentFactoryResolver, injector: Injector, data: any, classesToAdd: string[]): Promise { + attachViewToDom(parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type, componentResolveFactory: ComponentFactoryResolver, injector: Injector, data: any, classesToAdd: string[], wrapUserTemplateInIonPage: boolean): Promise { return new Promise((resolve) => { this.zone.run(() => { const crf = componentResolveFactory ? componentResolveFactory : this.defaultCfr; - const mountingData = attachViewToDom(crf, parentElement, hostElement, componentToMount, injector, this.appRef, data, classesToAdd); + const mountingData = attachViewToDom(crf, parentElement, hostElement, componentToMount, injector, this.appRef, data, classesToAdd, wrapUserTemplateInIonPage); resolve(mountingData); }); }); } - removeViewFromDom(childElement: HTMLElement): Promise { + removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement): Promise { return new Promise((resolve) => { this.zone.run(() => { - removeViewFromDom(childElement); + removeViewFromDom(parentElement, childElement); resolve(); }); }); } + } -export function removeViewFromDom(childElement: HTMLElement) { +export function removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) { const componentRef = elementToComponentRefMap.get(childElement); if (componentRef) { componentRef.destroy(); + if (parentElement.contains(childElement)) { + parentElement.removeChild(childElement); + } } } -export function attachViewToDom(crf: ComponentFactoryResolver, parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type, injector: Injector, appRef: ApplicationRef, data: any, classesToAdd: string[]): AngularMountingData { +export function attachViewToDom(crf: ComponentFactoryResolver, parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type, injector: Injector, appRef: ApplicationRef, data: any, classesToAdd: string[], wrapUserTemplateInIonPage: boolean): AngularMountingData { const componentProviders = ReflectiveInjector.resolve(getProviders(parentElement, data)); const componentFactory = crf.resolveComponentFactory(componentToMount); if (!hostElement) { hostElement = document.createElement(componentFactory.selector); } + + let mountingElement = hostElement; + if (wrapUserTemplateInIonPage) { + const ionPageElement = document.createElement('ion-page'); + hostElement.appendChild(ionPageElement); + mountingElement = ionPageElement; + } + const childInjector = ReflectiveInjector.fromResolvedProviders(componentProviders, injector); - const componentRef = componentFactory.create(childInjector, [], hostElement); + const componentRef = componentFactory.create(childInjector, [], mountingElement); for (const clazz of classesToAdd) { hostElement.classList.add(clazz); } @@ -71,8 +83,8 @@ export function attachViewToDom(crf: ComponentFactoryResolver, parentElement: HT return { componentFactory, - childInjector: childInjector, - componentRef: componentRef, + childInjector, + componentRef, instance: componentRef.instance, angularHostElement: componentRef.location.nativeElement, element: hostElement, diff --git a/packages/angular/src/providers/modal-controller.ts b/packages/angular/src/providers/modal-controller.ts index 02928e7965..7e24723419 100644 --- a/packages/angular/src/providers/modal-controller.ts +++ b/packages/angular/src/providers/modal-controller.ts @@ -31,11 +31,11 @@ export class ModalController implements FrameworkDelegate { attachViewToDom(elementOrContainerToMountTo: HTMLElement, elementOrComponentToMount: Type, _propsOrDataObj?: any, classesToAdd?: string[]): Promise { - return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd); + return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd, true); } - removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { - return this.angularComponentMounter.removeViewFromDom(childElement); + removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) { + return this.angularComponentMounter.removeViewFromDom(parentElement, childElement); } } diff --git a/packages/angular/src/providers/popover-controller.ts b/packages/angular/src/providers/popover-controller.ts index 860aae0b6e..cef8ea3f6a 100644 --- a/packages/angular/src/providers/popover-controller.ts +++ b/packages/angular/src/providers/popover-controller.ts @@ -31,11 +31,11 @@ export class PopoverController implements FrameworkDelegate { attachViewToDom(elementOrContainerToMountTo: HTMLElement, elementOrComponentToMount: Type, _propsOrDataObj?: any, classesToAdd?: string[]): Promise { - return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd); + return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd, false); } - removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { - return this.angularComponentMounter.removeViewFromDom(childElement); + removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) { + return this.angularComponentMounter.removeViewFromDom(parentElement, childElement); } }